信號量與普通整型變量的區(qū)別:
①信號量(semaphore)是非負(fù)整型變量,除了初始化之外,,它只能通過兩個(gè)標(biāo)準(zhǔn)原子操作:wait(semap) , signal(semap) ; 來進(jìn)行訪問,;
②操作也被成為PV原語(P來源于Dutch proberen"測試",V來源于Dutch verhogen"增加"),,而普通整型變量則可以在任何語句塊中被訪問,;
信號量與互斥鎖之間的區(qū)別:
1. 互斥量用于線程的互斥,信號線用于線程的同步,。
這是互斥量和信號量的根本區(qū)別,,也就是互斥和同步之間的區(qū)別。
互斥:是指某一資源同時(shí)只允許一個(gè)訪問者對其進(jìn)行訪問,,具有唯一性和排它性,。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的,。
同步:是指在互斥的基礎(chǔ)上(大多數(shù)情況),,通過其它機(jī)制實(shí)現(xiàn)訪問者對資源的有序訪問。在大多數(shù)情況下,,同步已經(jīng)實(shí)現(xiàn)了互斥,,特別是所有寫入資源的情況必定是互斥的。少數(shù)情況是指可以允許多個(gè)訪問者同時(shí)訪問資源
2. 互斥量值只能為0/1,,信號量值可以為非負(fù)整數(shù),。
也就是說,一個(gè)互斥量只能用于一個(gè)資源的互斥訪問,,它不能實(shí)現(xiàn)多個(gè)資源的多線程互斥問題,。信號量可以實(shí)現(xiàn)多個(gè)同類資源的多線程互斥和同步。當(dāng)信號量為單值信號量是,,也可以完成一個(gè)資源的互斥訪問,。
3. 互斥量的加鎖和解鎖必須由同一線程分別對應(yīng)使用,信號量可以由一個(gè)線程釋放,,另一個(gè)線程得到,。
信號量
信號量(Semaphore),,有時(shí)被稱為信號燈,是在多線程環(huán)境下使用的一種設(shè)施, 它負(fù)責(zé)協(xié)調(diào)各個(gè)線程, 以保證它們能夠正確,、合理的使用公共資源,。
信號量可以分為幾類:
2 二進(jìn)制信號量(binary semaphore):只允許信號量取0或1值,其同時(shí)只能被一個(gè)線程獲取,。
2 整型信號量(integer semaphore):信號量取值是整數(shù),,它可以被多個(gè)線程同時(shí)獲得,直到信號量的值變?yōu)?,。
2 記錄型信號量(record semaphore):每個(gè)信號量s除一個(gè)整數(shù)值value(計(jì)數(shù))外,,還有一個(gè)等待隊(duì)列List,其中是阻塞在該信號量的各個(gè)線程的標(biāo)識(shí),。當(dāng)信號量被釋放一個(gè),,值被加一后,系統(tǒng)自動(dòng)從等待隊(duì)列中喚醒一個(gè)等待中的線程,,讓其獲得信號量,,同時(shí)信號量再減一。
信號量通過一個(gè)計(jì)數(shù)器控制對共享資源的訪問,,信號量的值是一個(gè)非負(fù)整數(shù),,所有通過它的線程都會(huì)將該整數(shù)減一。如果計(jì)數(shù)器大于0,,則訪問被允許,,計(jì)數(shù)器減1;如果為0,,則訪問被禁止,,所有試圖通過它的線程都將處于等待狀態(tài)。
計(jì)數(shù)器計(jì)算的結(jié)果是允許訪問共享資源的通行證,。因此,,為了訪問共享資源,線程必須從信號量得到通行證,, 如果該信號量的計(jì)數(shù)大于0,,則此線程獲得一個(gè)通行證,這將導(dǎo)致信號量的計(jì)數(shù)遞減,,否則,此線程將阻塞直到獲得一個(gè)通行證為止,。當(dāng)此線程不再需要訪問共享資源時(shí),,它釋放該通行證,這導(dǎo)致信號量的計(jì)數(shù)遞增,,如果另一個(gè)線程等待通行證,,則那個(gè)線程將在那時(shí)獲得通行證,。
Semaphore可以被抽象為五個(gè)操作:
- 創(chuàng)建 Create
- 等待 Wait:
線程等待信號量,如果值大于0,,則獲得,,值減一;如果只等于0,,則一直線程進(jìn)入睡眠狀態(tài),,知道信號量值大于0或者超時(shí)。
-釋放 Post
執(zhí)行釋放信號量,,則值加一,;如果此時(shí)有正在等待的線程,則喚醒該線程,。
-試圖等待 TryWait
如果調(diào)用TryWait,,線程并不真正的去獲得信號量,還是檢查信號量是否能夠被獲得,,如果信號量值大于0,,則TryWait返回成功;否則返回失敗,。
-銷毀 Destroy
信號量,,是可以用來保護(hù)兩個(gè)或多個(gè)關(guān)鍵代碼段,這些關(guān)鍵代碼段不能并發(fā)調(diào)用,。在進(jìn)入一個(gè)關(guān)鍵代碼段之前,,線程必須獲取一個(gè)信號量。如果關(guān)鍵代碼段中沒有任何線程,,那么線程會(huì)立即進(jìn)入該框圖中的那個(gè)部分,。一旦該關(guān)鍵代碼段完成了,那么該線程必須釋放信號量,。其它想進(jìn)入該關(guān)鍵代碼段的線程必須等待直到第一個(gè)線程釋放信號量,。為了完成這個(gè)過程,需要?jiǎng)?chuàng)建一個(gè)信號量,,然后將Acquire Semaphore VI以及Release Semaphore VI分別放置在每個(gè)關(guān)鍵代碼段的首末端,。確認(rèn)這些信號量VI引用的是初始創(chuàng)建的信號量。 動(dòng)作\系統(tǒng)
Win32
POSIX
創(chuàng)建
CreateSemaphore
sem_init
等待
WaitForSingleObject
sem _wait
釋放
ReleaseMutex
sem _post
試圖等待
WaitForSingleObject
sem _trywait
銷毀
CloseHandle
sem_destroy
互斥量(Mutex)
互斥量表現(xiàn)互斥現(xiàn)象的數(shù)據(jù)結(jié)構(gòu),,也被當(dāng)作二元信號燈,。一個(gè)互斥基本上是一個(gè)多任務(wù)敏感的二元信號,它能用作同步多任務(wù)的行為,,它常用作保護(hù)從中斷來的臨界段代碼并且在共享同步使用的資源,。
Mutex本質(zhì)上說就是一把鎖,提供對資源的獨(dú)占訪問,所以Mutex主要的作用是用于互斥,。Mutex對象的值,,只有0和1兩個(gè)值。這兩個(gè)值也分別代表了Mutex的兩種狀態(tài),。值為0, 表示鎖定狀態(tài),,當(dāng)前對象被鎖定,用戶進(jìn)程/線程如果試圖Lock臨界資源,,則進(jìn)入排隊(duì)等待,;值為1,表示空閑狀態(tài),,當(dāng)前對象為空閑,,用戶進(jìn)程/線程可以Lock臨界資源,之后Mutex值減1變?yōu)?,。
Mutex可以被抽象為四個(gè)操作:
- 創(chuàng)建 Create
- 加鎖 Lock
- 解鎖 Unlock
- 銷毀 Destroy
Mutex被創(chuàng)建時(shí)可以有初始值,,表示Mutex被創(chuàng)建后,是鎖定狀態(tài)還是空閑狀態(tài),。在同一個(gè)線程中,,為了防止死鎖,系統(tǒng)不允許連續(xù)兩次對Mutex加鎖(系統(tǒng)一般會(huì)在第二次調(diào)用立刻返回),。也就是說,,加鎖和解鎖這兩個(gè)對應(yīng)的操作,需要在同一個(gè)線程中完成,。
不同操作系統(tǒng)中提供的Mutex函數(shù): 動(dòng)作\系統(tǒng)
Win32
Linyx
Solaris
創(chuàng)建
CreateMutex
pthread_mutex_init
mutex_init
加鎖
WaitForSingleObject
pthread_mutex_lock
mutex_lock
解鎖
ReleaseMutex
pthread_mutex_unlock
mutex_unlock
銷毀
CloseHandle
pthread_mutex_destroy
mutex_destroy