互斥信号量和二进制信号量
互斥信號量和二進制信號量的區別
??????
互斥型信號量必須是同一個任務申請,同一個任務釋放,其他任務釋放無效。同一個任務可以遞歸申請。
?????? 二進制信號量,一個任務申請成功后,可以由另一個任務釋放。
二進制信號量實現任務互斥:
???? 打印機資源只有一個,abc三個任務共享,當a取得使用權后,為了防止其他任務錯誤地釋放了信號量(),必須將打印機房的門關起來(進入臨界段),用完后,釋放信號量,再把門打開(出臨界段),其他任務再進去打印。(而互斥型信號量由于必須由取得信號量的那個任務釋放,故不會出現其他任務錯誤地釋放了信號量的情況出現,故不需要有臨界段?;コ庑托盘柫渴嵌M制信號量的子集。)
二進制信號量實現任務同步:
???? a任務一直等待信號量,b任務定時釋放信號量,完成同步功能
理解互斥量和信號量 作者: JuKevin
互斥量(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. 互斥量的加鎖和解鎖必須由同一線程分別對應使用,信號量可以由一個線程釋放,另一個線程得到。
總結
以上是生活随笔為你收集整理的互斥信号量和二进制信号量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 直击神舟十四号载人飞船发射:已发射升空
- 下一篇: 联想29英寸超宽带鱼屏仅1099元:90