作業系統的同步機制是老話題了,不過技術的東西放久不用了就容易忘記,在這裡就訊號量為大家整理一下思緒。
在linux系統中,訊號量是一種可以睡眠的鎖。如果程序a希望占有乙個正在被程序b使用的訊號量時,程序a會被推入等待佇列,然後睡眠。直到程序b將持有的訊號量釋放,處於等待佇列中的程序a才會被喚醒,並獲得訊號量。
從訊號量的特點所得出的一些結論,如下:
如何在自旋鎖和訊號量之間做個選擇呢,即臨界區短就用自旋鎖,臨界區長就用訊號量,當然禁止睡眠的地方是不可以使用訊號量的。
訊號量的另乙個特性是,同一時刻允許任意數量的持有者,相比自旋鎖同一時刻只能允許乙個持有者,訊號量在某些場合是非常有優勢的。
因此在linux中,訊號量又分為兩種:
1. 同一時刻可被多個持有者占有的訊號量稱為計數訊號量 sem
2. 同一時刻只允許乙個持有者占用的訊號量稱為互斥訊號量 mutex
互斥訊號量用的比較多一些,訊號量到底可以允許幾個持有者,是在宣告訊號量的時候用引數控制的。
struct semaphore ,這便是linux中訊號量的資料型別,可以通過一下方式靜態的宣告訊號量:
static declare_semaphore_generic(name, count);
其中引數,name自然是指訊號量的名字,count就是剛才提到過的持有者的數量,如果希望建立乙個互斥量,可以簡單的使用下面的巨集:
static declare_mutex(name);
當你需要用kmalloc動態建立乙個訊號量時,可以用sem_init(sem, count)來初始化動態建立的訊號量,當然用下面的簡單呼叫可以初始化動態建立的互斥訊號量:
init_mutex(sem);
說了這麼多,下面貼上一段**,和大家說說從聲名,到使用乙個訊號量的完整過程:
/* 在全域性位置上,定義並聲名乙個互斥訊號量, 名字為test_sem */
static declare_mutex(test_sem);
/* 在某個函式中, 希望獲取訊號量 */
if (down_interruptible(&test_sem))
/* 臨界區 */
......
/* 釋放訊號量 */
up(&test_sem);
我們說說down_interruptible,它會試圖獲取訊號量,但如果發現其已經被持有,down_interruptible會讓當前的程序進入等待佇列並睡眠。當然,這種睡眠是可以被打斷的,可以響應訊號,如果使用另乙個獲取訊號量的函式 - down(),那就不能被訊號打斷,會一直睡在那裡,直到希望獲取的訊號量被釋放。
linux同步機制
一.併發控制 1 自旋鎖 得不到資源,會原地打轉,直到獲得資源為止 定義自旋鎖 spinlock t spin 初始化自旋鎖 spin lock init lock 獲得自旋鎖 spin lock lock 獲得自旋鎖,如果能立即獲得,則馬上返回,否則自旋在那裡,直到該自旋鎖的保持者釋放 spin ...
linux同步機制
原子操作 原子操作是由編譯器來保證的,保證乙個執行緒對資料的操作不會被其他執行緒打斷。當執行緒正在對乙個變數操作而這個操作過程不想被其他執行緒打斷時,可以用原子操作,原子操作結構體 atomic t 原子操作缺點 會阻塞優先順序很高的執行緒。自旋鎖 當乙個執行緒在讀寫乙個共享資源時,加上自旋鎖,其他...
linux同步機制
1 自旋鎖 獲得自旋鎖之後禁止核心搶占,但可以被中斷上半部打斷。執行於中斷上下文 單cpu不可搶占核心 空操作 單cpu可搶占核心 禁止核心搶占,不發生自旋 多cpu可搶占核心 禁止核心搶占 自旋 2 互斥鎖 核心可以搶占,可以被其他程序搶占,執行於程序上下文 3 讀寫鎖 4 順序鎖 對讀寫鎖的一種...