本文的目的是要分析訊號量內部的實現流程,不深入訊號量底層的實現細節aqs(將會有另外一篇文章分析),讓讀者能夠理解訊號量內部結構和呼叫流程。
semaphore:內部持有一系列的許可(permit),acquire操作會被阻塞直到有足夠多的許可可用,最後會占用這些許可;release操作會歸還許可讓阻塞的acquire操作獲取。semaphore作用是限制多執行緒同時正確某一資源(資源可以是某個物件,可以是某種行為,例如建立某一物件的權利,銷毀某一物件的權利)。
從上面的定義,可以看到主要有幾個概念:許可,獲取,和釋放。semaphore訊號量的作用顯然就是維護許可,提供許可獲取和釋放功能。首先,我們可以想到許可是否可用,顯然許可是具有一定狀態的,例如0:代表不可用,1:代表可用等,那麼semaphore訊號量是如何標識許可的狀態特徵的呢?
獲取:肯定有個獲取者(accquirer),獲取者自身有以下特點:1)優先順序不一樣,有些高,有些低,就好比富人和窮人;2)獲取者素質不太一樣,有些獲取者霸佔許可一直不歸還,有些獲取者及時歸還;3) 獲取者有可能需要同時獲取多個許可的需求;獲取者在獲取許可過程中顯然也會有一些特點:1)獲取者可能大量同時獲取相同的許可,導致競爭非常激烈;2)獲取者如果沒有獲取許可時一直等待,有些希望有許可時在通知他們;3)獲取者獲取並持有許可用,獲取者死亡,那麼許可怎麼歸還給semaphore。
釋放:獲取者在釋放過程中,相對來說就比較簡單,只需要通知semaphore,告訴不需要許可了即可。
因此,下面將從semaphore,獲取者和許可三者關係出發,分析三者之間的關係。
當我們建立semaphore時,需要制定許可個數以及是否採用公平同步器,在semaphore中,公正semaphore是指當semaphore中有獲取許可操作時不允許當前獲取許可操作成功,直接返回失敗;不公平semaphore則獲取操作基於cas機制不斷操作處理,不分先後,這會導致後面的獲取操作有可能先於前面操作獲得許可,呈現不公平。
先看semaphore結構,整體包括獲取許可呼叫函式,超時獲取許可呼叫函式,維護許可資訊函式,和釋放等操作。
首先分析acquire方法,該方法支援執行緒中斷,一旦發生執行緒中斷,直接跳出獲取操作,向上丟擲interrputedexception異常。
publicvoid
acquire
() throws
interruptedexception
進入sync.acquiresharedinterruptibly(integer)方法。首先及時校驗thread是否處於已中斷狀態,之後嘗試獲取許可,如果獲取失敗,進入阻塞獲取流程(在這個迴圈中會不斷檢測線程是否發生中斷)。
publicfinal void
acquiresharedinterruptibly
(int
arg)
throws
interruptedexception
進入tryacquire方法,該方法主要是獲取訊號量,不成功返回false,成功返回true,不阻塞,有明確結果返回。
publicboolean
tryacquire
()
進入tryacquire(int,long,timeuint)方法,首先判斷是否發生執行緒中斷,如未發生中斷則進入tryacquiresharednanos方法(該方法會首先獲取一次許可,未獲取許可則進入指定時間段內輪詢)。
publicboolean
tryacquire
(int
permits
, long
timeout
, timeunit unit)
throws
interruptedexception
OpenMP程式設計 同步機制
nowait用來取消柵障 void test12 pragma omp for for int j 0 j 100 j 顯式同步柵障 在barrier處進行了同步,然後執行後邊的for迴圈。void test13 std cout this will printed twice.std endl s...
五 Golang併發程式設計與同步機制 死鎖與條件變數
1.單go程自己死鎖 channel 應該在 至少 2 個以上的 go程中進行通訊。否則死鎖!func main 2.go程間channel訪問順序導致死鎖 使用channel一端讀 寫 要保證另一端寫 讀 操作,同時有機會執行。否則死鎖。func main num ch 主go程直接結束 fmt....
併發程式設計之AQS的同步原理
aqs abstractqueuedsynchronizer 抽象佇列同步器。aqs的同步狀態 aqs使用乙個int成員變數來表示同步狀態,通過內建的fifo佇列來完成獲取資源執行緒的排隊工作。aqs使用cas對該同步狀態進行原子操作實現對其值的修改。private volatile int sta...