互斥量(Mutex)數據結構
互斥量表現互斥現象的數據結構,也被看成二元信號燈。一個互斥基本上是一個多任務敏感的二元信號,它能用做同步多任務的行爲,它經常使用做保護從中斷來的臨界段代碼而且在共享同步使用的資源。多線程
Mutex 本質上說就是一把鎖,提供對資源的獨佔訪問,因此Mutex主要的做用是用於互斥。Mutex對象的值,只有0和1兩個值。這兩個值也分別表明了 Mutex的兩種狀態。值爲0, 表示鎖定狀態,當前對象被鎖定,用戶進程/線程若是試圖Lock臨界資源,則進入排隊等待;值爲1,表示空閒狀態,當前對象爲空閒,用戶進程/線程能夠 Lock臨界資源,以後Mutex值減1變爲0。併發
Mutex能夠被抽象爲四個操做:函數
- 建立 Createpost
- 加鎖 Lockui
- 解鎖 Unlockspa
- 銷燬 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. 互斥量值只能爲0/1,信號量值能夠爲非負整數。
也就是說,一個互斥量只能用於一個資源的互斥訪問,它不能實現多個資源的多線程互斥問題。信號量能夠實現多個同類資源的多線程互斥和同步。當信號量爲單值信號量是,也能夠完成一個資源的互斥訪問。
3. 互斥量的加鎖和解鎖必須由同一線程分別對應使用,信號量能夠由一個線程釋放,另外一個線程獲得。