URL: http://blog.csdn.net/cute810326/article/details/4535612
互斥信号量和二進制信号量的差別
互斥型信号量必須是同一個任務申請,同一個任務釋放,其他任務釋放無效。同一個任務可以遞歸申請。
二進制信号量,一個任務申請成功後,可以由另一個任務釋放。
二進制信号量實作任務互斥:
列印機資源隻有一個,abc三個任務共享,當a取得使用權後,為了防止其他任務錯誤地釋放了信号量(),必須将列印機房的門關起來(進入臨界段),用完後,釋放信号量,再把門打開(出臨界段),其他任務再進去列印。(而互斥型信号量由于必須由取得信号量的那個任務釋放,故不會出現其他任務錯誤地釋放了信号量的情況出現,故不需要有臨界段。互斥型信号量是二進制信号量的子集。)
二進制信号量實作任務同步:
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. 互斥量的加鎖和解鎖必須由同一線程分别對應使用,信号量可以由一個線程釋放,另一個線程得到。