互斥型訊號量必須是同乙個任務申請,同乙個任務釋放,其他任務釋放無效。同乙個任務可以遞迴申請。
二進位制訊號量,乙個任務申請成功後,可以由另乙個任務釋放。
二進位制訊號量實現任務互斥:
印表機資源只有乙個,
abc三個任務共享,當
a取得使用權後,為了防止其他任務錯誤地釋放了訊號量
(),必須將印表機房的門關起來
(進入臨界段
),用完後,釋放訊號量,再把門開啟
(出臨界段
),其他任務再進去列印。
(而互斥型訊號量由於必須由取得訊號量的那個任務釋放,故不會出現其他任務錯誤地釋放了訊號量的情況出現,故不需要有臨界段。互斥型訊號量是二進位制訊號量的子集。)
二進位制訊號量實現任務同步:
a任務一直等待訊號量,
b任務定時釋放訊號量,完成同步功能
互斥量(mutex)
互斥量表現互斥現象的資料結構,也被當作二元訊號燈。乙個互斥基本上是乙個多工敏感的二元訊號,它能用作同步多工的行為,它常用作保護從中斷來的臨界段**並且在共享同步使用的資源。
mutex
本質上說就是一把鎖,提供對資源的獨佔訪問,所以
mutex
主要的作用是用於互斥。
mutex
物件的值,只有0和
1兩個值。這兩個值也分別代表了
mutex
的兩種狀態。值為
0, 表示鎖定狀態,當前物件被鎖定,使用者程序
/執行緒如果試圖
lock
臨界資源,則進入排隊等待;值為
1,表示空閒狀態,當前物件為空閒,使用者程序
/執行緒可以
lock
臨界資源,之後
mutex值減1
變為0。mutex
可以被抽象為四個操作:
- 建立
create
- 加鎖
lock
- 解鎖
unlock
- 銷毀
destroy
mutex
被建立時可以有初始值,表示
mutex
被建立後,是鎖定狀態還是空閒狀態。在同乙個執行緒中,為了防止死鎖,系統不允許連續兩次對
mutex加鎖(
系統一般會在第二次呼叫立刻返回
)。也就是說,加鎖和解鎖這兩個對應的操作,需要在同乙個執行緒中完成。
不同作業系統中提供的
mutex
函式: 動作/
系統 win32
linyx
solaris
建立 createmutex
pthread_mutex_init
mutex_init
加鎖 waitforsingleobject
pthread_mutex_lock
mutex_lock
解鎖 releasemutex
pthread_mutex_unlock
mutex_unlock
銷毀 closehandle
pthread_mutex_destroy
mutex_destroy
訊號量訊號量
(semaphore)
,有時被稱為訊號燈,是在多執行緒環境下使用的一種設施
, 它負責協調各個執行緒
, 以保證它們能夠正確、合理的使用公共資源。
訊號量可以分為幾類:
二進位制訊號量
(binary semaphore)
:只允許訊號量取0或
1值,其同時只能被乙個執行緒獲取。
整型訊號量(
integer semaphore)
訊號量取值是整數,它可以被多個執行緒同時獲得,直到訊號量的值變為0。
記錄型訊號量(
record semaphore)
每個訊號量
s除乙個整數值
value
(計數)外,還有乙個等待佇列
list
,其中是阻塞在該訊號量的各個執行緒的標識。當訊號量被釋放乙個,值被加一後,系統自動從等待佇列中喚醒乙個等待中的執行緒,讓其獲得訊號量,同時訊號量再減一。
訊號量通過乙個計數器控制對共享資源的訪問,訊號量的值是乙個非負整數,所有通過它的執行緒都會將該整數減一。如果計數器大於
0,則訪問被允許,計數器減
1;如果為
0,則訪問被禁止,所有試圖通過它的執行緒都將處於等待狀態。
計數器計算的結果是允許訪問共享資源的通行證。因此,為了訪問共享資源,執行緒必須從訊號量得到通行證,
如果該訊號量的計數大於
0,則此執行緒獲得乙個通行證,這將導致訊號量的計數遞減,否則,此執行緒將阻塞直到獲得乙個通行證為止。當此執行緒不再需要訪問共享資源時,它釋放該通行證,這導致訊號量的計數遞增,如果另乙個執行緒等待通行證,則那個執行緒將在那時獲得通行證。
semaphore
可以被抽象為五個操作: -
建立create
- 等待
wait:
執行緒等待訊號量,如果值大於
0,則獲得,值減一;如果只等於
0,則一直執行緒進入睡眠狀態,知道訊號量值大於
0或者超時。
-釋放post
執行釋放訊號量,則值加一;如果此時有正在等待的執行緒,則喚醒該執行緒。
-試圖等待
trywait
如果呼叫
trywait
,執行緒並不真正的去獲得訊號量,還是檢查訊號量是否能夠被獲得,如果訊號量值大於0,則
trywait
返回成功;否則返回失敗。
-銷毀destroy
訊號量,是可以用來保護兩個或多個關鍵**段,這些關鍵**段不能併發呼叫。在進入乙個關鍵**段之前,執行緒必須獲取乙個訊號量。如果關鍵**段中沒有任何執行緒,那麼執行緒會立即進入該框圖中的那個部分。一旦該關鍵**段完成了,那麼該執行緒必須釋放訊號量。其它想進入該關鍵**段的執行緒必須等待直到第乙個執行緒釋放訊號量。為了完成這個過程,需要建立乙個訊號量,然後將
acquire semaphore vi
以及release semaphore vi
分別放置在每個關鍵**段的首末端。確認這些訊號量
vi引用的是初始建立的訊號量。動作/
系統 win32
posix
建立 createsemaphore
sem_init
等待 waitforsingleobject
sem _wait
釋放 releasemutex
sem _post
試圖等待
waitforsingleobject
sem _trywait
銷毀 closehandle
sem_destroy
1. 互斥量用於執行緒的互斥,訊號量用於執行緒的同步。——
這是互斥量和訊號量的根本區別,也就是互斥和同步之間的區別。 2.
互斥量無法保證執行緒對資源的有序訪問,訊號量可以。
互斥是指某一資源同時只允許乙個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。(
cute
:好比乙個別墅,同時只能賣個乙個人。這個人可以在門上加上任意多的鎖(申請多次),但是鎖必須由這個人開啟,因為只有他掌握著鑰匙。如果別的人真的想控制這個別墅的大門,則它首先應該把這個別墅買下來(別墅的主人放棄所有權))
同步是指在互斥的基礎上(大多數情況)
,通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源
(cute
:相當於圖書館閱覽室的書卡,你申請的時候
-1,另乙個人還的時候則可以
+1,我們都可以修改書卡的當前可用數目,這個權利是不獨屬於任何人的。)
3. 互斥量值只能為
0/1,訊號量值可以為非負整數。
也就是說,乙個互斥量只能用於乙個資源的互斥訪問,它不能實現多個資源的多執行緒互斥問題。訊號量可以實現多個同類資源的多執行緒互斥和同步。當訊號量為單值訊號量是,也可以完成乙個資源的互斥訪問。
4. 互斥量的加鎖和解鎖必須由同一執行緒分別對應使用,訊號量可以由乙個執行緒釋放,另乙個執行緒得到。
訊號量 二值訊號量
訊號量 二值訊號量 訊號量是作業系統的重要部分,訊號量一般用來進行資源管理和任務同步。freertos中訊號量分為二值訊號量 互斥訊號量 計數訊號量和遞迴互斥訊號量,應用場景各不同。二值訊號量通常用於互斥訪問或同步,二值訊號量和互斥訊號量非常相似,但互斥訊號量有優先順序,二值訊號量沒有。因此二值訊號...
訊號量 互斥量
lonelycatcher if only as first.來自 訊號量用在多執行緒多工同步的,乙個執行緒完成了某乙個動作就通過訊號量告訴別的執行緒,別的執行緒再進行某些動作 大家都在semtake的時候,就阻塞在 而互斥鎖是用在多執行緒多工互斥的,乙個執行緒占用了某乙個資源,那麼別的執行緒就無法...
訊號量和互斥量
1.互斥量用於執行緒的互斥,訊號線用於執行緒的同步。這是互斥量和訊號量的根本區別,也就是互斥和同步之間的區別。互斥 是指某一資源同時只允許乙個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。同步 是指在互斥的基礎上 大多數情況 通過其它機制實現訪問者對資...