1. 程式人生 > >linux驅動 併發策略

linux驅動 併發策略

訪問共享資源的程式碼區塊叫“臨界區”,臨界區需要以某種互斥機制加以保護:自旋鎖、訊號量等。
互斥訪問:一個執行單元在訪問共享資源的時候,其他的執行單元被禁止訪問。

訊號量:在Liunx中的訊號量是一種睡眠鎖。假如程序A先持有訊號量F,然後程序B試圖獲取已經被程序A持有的訊號量F時(假如訊號量F資源值為1),訊號量會將B程序推入等待佇列,然後讓

            其睡眠。當持有訊號量的程序A將訊號量F釋放後,程序B才會被喚醒,從而獲得這個訊號量,繼續執行程序B程式碼。
            PS:訊號量的睡眠特性,使得訊號量適用於鎖會被長時間持有的情況;訊號量只能在程序中使用,不能再中斷中使用。
訊號量基本使用形式:
     (1) 定義訊號量:struct semaphore sem;
     (2) 初始化訊號量:void sema_init(struct semaphore *sem, int val);
     (3) 初始化互斥訊號量:
           void init_MUTEX(struct semaphore *sem);
           等同於:sema_int(struct semaphore*sem, 1);
獲得訊號量:
     (1) void down(struct semaphore *sem);
          此函式用於獲得訊號量sem,它會導致睡眠,因此不能用於中斷上下文
     (2) int down_interruptible(struct semaphore *sem);
          同down(),差異在於因為down()而進入睡眠狀態的程序不能被訊號打斷,而因為down_interruptible()而進入睡眠狀態的程序能被訊號打斷,而訊號會導致該函式返回,這時候函式返回非0;
     (3) int down_trylock(struct semaphore *sem);
          該函式嘗試獲得訊號量sem,如果能夠立即獲得,它就獲得該訊號量返回0,否則,返回非0值,它不能導致呼叫者睡眠,可以在中斷上下文使用。
釋放訊號量:
     void up(struct semaphore *sem);
     該函式釋放訊號量sem,喚醒等待者。

使用訊號量的注意事項:
      (1)可以長期加鎖;
      (2)只能用於程序上下文,不能用於中斷上下文;
      (3)在持有自旋鎖的同時,不能持有訊號量;

訊號量操作:

struct semaphore sem;//定義
static  inline void sema_init(struct semaphore *sem,int val);//初始化
void down (struct semaphore *sem) ;// 獲取訊號量,沒獲取到就使當前程序睡眠
另外一個 downtrylock(struct semaphore *sem);  不睡眠  立即返回
extern void up (struct semaphore *sem);//釋放訊號量

原子操作:

atomic_t  n; //定義一個原子變數

atomic_set(&n,2);//將變數初始值設為2

atmoic_add(5,&n);//將變數加5

atomic_dec(&n);//將變數減1

自旋鎖操作:
spinlock_t lock;//定義
spin_lock_init(&lock);//初始化
spin_lock(&lock);//獲取,沒獲取就被阻塞 spin_trylock(&lock)不阻塞  立即返回 成功返回非0  不成功返回0
臨界區程式碼
spin_unlock(&lock);//釋放

互斥體
互斥體實現了“互相排斥”(mutual exclusion)同步的簡單形式(所以名為互斥體
(mutex))。互斥體禁止多個執行緒同時進入受保護的程式碼“臨界區”(critical section)。因此,在任意時刻,只有一個執行緒被允許進入這樣的程式碼保護區。任何執行緒在進入臨界區之前,必須獲取(acquire)與此區域相關聯的互斥體的所有權。如果已有另一執行緒擁有了臨界區的互斥體,其他執行緒就不能再進入其中。這些執行緒必須等待,直到當前的屬主執行緒釋放(release)該互斥體。
使用;
struct  mutex my_mutex;//定義
mutex_init(&my_mutex);//初始化
mutex_lock(struct mutex *lock) ;//另獲取外一個 mutex_trylock(struct mutex *lock)(沒獲取到也補睡眠,立即返回)

void mutex_unlock(struct mutex *lock);//釋放