本文轉載自信號量與互斥鎖,如有侵權,請及時聯系博主刪除。
1. 信號量與普通整型變量的區別:
①信號量(semaphore)是非負整型變量,除了初始化之外,它只能通過兩個標準原子操作:wait(semap) , signal(semap) ; 來進行訪問;
②操作也被成為PV原語(P來源于Dutch proberen"測試",V來源于Dutch verhogen"增加"),而普通整型變量則可以在任何語句塊中被訪問;
2. 信號量與互斥鎖之間的區別:
- 互斥量用于線程的互斥,信號線用于線程的同步。
這是互斥量和信號量的根本區別,也就是互斥和同步之間的區別。
互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。
同步:是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源
- 互斥量值只能為0/1,信號量值可以為非負整數。
也就是說,一個互斥量只能用于一個資源的互斥訪問,它不能實現多個資源的多線程互斥問題。信號量可以實現多個同類資源的多線程互斥和同步。當信號量為單值信號量是,也可以完成一個資源的互斥訪問。
- 互斥量的加鎖和解鎖必須由同一線程分別對應使用,信號量可以由一個線程釋放,另一個線程得到。
3. 信號量
信號量(Semaphore),有時被稱為信號燈,是在多線程環境下使用的一種設施, 它負責協調各個線程, 以保證它們能夠正確、合理的使用公共資源。
信號量可以分為幾類:
二進制信號量(binary semaphore):只允許信號量取0或1值,其同時只能被一個線程獲取。
整型信號量(integer semaphore):信號量取值是整數,它可以被多個線程同時獲得,直到信號量的值變為0。
記錄型信號量(record semaphore):每個信號量s除一個整數值value(計數)外,還有一個等待隊列List,其中是阻塞在該信號量的各個線程的標識。當信號量被釋放一個,值被加一后,系統自動從等待隊列中喚醒一個等待中的線程,讓其獲得信號量,同時信號量再減一。
信號量通過一個計數器控制對共享資源的訪問,信號量的值是一個非負整數,所有通過它的線程都會將該整數減一。如果計數器大于0,則訪問被允許,計數器減1;如果為0,則訪問被禁止,所有試圖通過它的線程都將處于等待狀態。
計數器計算的結果是允許訪問共享資源的通行證。因此,為了訪問共享資源,線程必須從信號量得到通行證, 如果該信號量的計數大于0,則此線程獲得一個通行證,這將導致信號量的計數遞減,否則,此線程將阻塞直到獲得一個通行證為止。當此線程不再需要訪問共享資源時,它釋放該通行證,這導致信號量的計數遞增,如果另一個線程等待通行證,則那個線程將在那時獲得通行證。
4. 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
5. 互斥量(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
本文轉載自信號量與互斥鎖,如有侵權,請及時聯系博主刪除。