訊號量(semaphore)是作業系統用來解決併發中的互斥和同步問題的一種方法。 訊號量是乙個與佇列有關的整型變數,其資料結構為乙個值和乙個指標,指標指向等待該訊號量的下乙個程序。你可以把它想象成乙個數後面拖著一條排隊的佇列,那訊號量拖著的那個佇列就是用來放正在排隊想要使用這一資源的程序,如圖:
那訊號量的值
s代表什麼意思呢?
訊號量的值與相應資源的使用情況有關:s
>0:當前有可用資源,
表示當前可用資源的數量為s
;s=0:資源都被占用,
表示當前可用資源的數量為0;
s<0:資源都被占用,
其絕對值表示等待使用該資源的程序個數
,即還有
s個程序正在排隊
注意,訊號量的值僅能由
訊號量機制
來改變,
即利用pv操作來對訊號量進行處理。
一般來說,訊號量
s>=0時,
s表示可用資源的數量。執行一次
p操作意味著請求分配乙個單位資源,因此
s的值減1;當
s<0
時,表示已經沒有可用資源,請求者必須等待別的程序釋放該類資源,它才能執行下去。而執行乙個
v操作意味著釋放乙個單位資源,因此
s的值加1;若
s<=0時
,表示有某些程序正在等待該資源,因此要喚醒乙個等待狀態的程序,使之執行下去。
1在**中我們可以看到有兩個對訊號量的struct
semaphore;56
void
semwait(semaphore s)12}
1314
void
semsignal(semaphore s)
20 }
count值和阻塞佇列的操作,乙個是semwait,乙個是semsignal,前者也被稱為p操作,後者也被稱為v操作。
semwait
:p操作(wait):申請乙個單位資源,程序進入;
經典偽**:
1semsignalwait(s)
:v操作(signal):釋放乙個單位資源,程序出來;
經典偽**:
1當申請資源的時候,資源數signal(s)
count值-
-,我們注意到資源數
,如果在--
之後<0,那麼這個這個程序就會加入到等待佇列。
為什麼這個條件設定成
<0呢?其實很好理解,當這個資源已經其他程序占有完了,即為0或者負數,那麼新程序要申請這個資源時資源數再減1必然count<0,那麼這個程序就要被被阻塞,進入阻塞佇列
再看semsignal操作
乙個程序終會使用完這個程序,然後離開,那麼此時可用資源數++
為什麼這個條件設定成
<=0呢?乙個程序用完資源走了,count++,如果還有程序在排隊(count即值是-
1或者更小),那++
之後必然
count<=0,此時就喚醒乙個排隊中的程序。
pv操作的意義
:我們用訊號量及
pv操作來實現程序的同步和互斥。
pv操作屬於程序的低階通訊。
使用pv
操作實現程序互斥時應該注意的是:(1
)每個程式中使用者實現互斥的p、
v操作必須成對出現,先做
p操作,進臨界區,後做
v操作,出臨界區。若有多個分支,要認真檢查其成對性。(2
)p、v
操作應分別緊靠臨界區的頭尾部,臨界區的**應盡可能短,不能有死迴圈。(3
)互斥訊號量的初值一般為1。
semwait(s):請求分配乙個資源。
semsignal(s):釋放乙個資源。
semwait、semsignal操作必須成對出現。
多個semwait操作的次序不能顛倒,否則可能導致死鎖。
多個semsignal操作的次序可任意。
用於互斥時,位於同一程序內;
用於同步時,交錯出現於兩個合作程序內。
且在前事件後加
semsignal,在後事件前加semwait,比如先刷牙再吃飯,那刷牙這個事件後加semsignal,在吃飯這個事件前加semwait
互斥關係:緩衝區是臨界資源,各程序互斥訪問
訊號量與互斥鎖
訊號量與普通整型變數的區別 訊號量 semaphore 是非負整型變數,除了初始化之外,它只能通過兩個標準原子操作 wait semap signal semap 來進行訪問 操作也被成為pv原語 p 於dutch proberen 測試 v 於 dutch verhogen 增加 而普通整型變數則...
訊號量與互斥鎖
原文 訊號量與普通整型變數的區別 訊號量 semaphore 是非負整型變數,除了初始化之外,它只能通過兩個標準原子操作 wait semap signal semap 來進行訪問 操作也被成為pv原語 p 於dutch proberen 測試 v 於 dutch verhogen 增加 而普通整型...
訊號量與互斥鎖
訊號量與普通整型變數的區別 訊號量 semaphore 是非負整型變數,除了初始化之外,它只能通過兩個標準原子操作 wait semap signal semap 來進行訪問 操作也被成為pv原語 p 於dutch proberen 測試 v 於 dutch verhogen 增加 而普通整型變數則...