信號量與互斥鎖

線程同步(互斥鎖與信號量的作用與區別)

“信號量用在多線程多任務同步的,一個線程完成了某一個動作就通過信號量告訴別的線程,別的線程再進行某些動作(大家都在semtake的時候,就阻塞在 哪里)。而互斥鎖是用在多線程多任務互斥的,一個線程占用了某一個資源,那么別的線程就無法訪問,直到這個線程unlock,其他的線程才開始可以利用這 個資源。比如對全局變量的訪問,有時要加鎖,操作完了,在解鎖。有的時候鎖和信號量會同時使用的”

也就是說,信號量不一定是鎖定某一個資源,而是流程上的概念,比如:有A,B兩個線程,B線程要等A線程完成某一任務以后再進行自己下面的步驟,這個任務 并不一定是鎖定某一資源,還可以是進行一些計算或者數據處理之類。而線程互斥量則是“鎖住某一資源”的概念,在鎖定期間內,其他線程無法對被保護的數據進 行操作。在有些情況下兩者可以互換。

兩者之間的區別:

作用域

信號量: 進程間或線程間(linux僅線程間的無名信號量pthread semaphore)

互斥鎖: 線程間

上鎖時?

信號量: 只要信號量的value大于0,其他線程就可以sem_wait成功,成功后信號量的value減一。若value值不大于0,則sem_wait使得線程阻塞,直到sem_post釋放后value值加一,但是sem_wait返回之前還是會將此value值減一

互斥鎖: 只要被鎖住,其他任何線程都不可以訪問被保護的資源

以下是信號燈(量)的一些概念:

信號燈與互斥鎖和條件變量的主要不同在于”燈”的概念,燈亮則意味著資源可用,燈滅則意味著不可用。如果說后兩中同步方式側重于”等待”操作,即資 源不可用的話,信號燈機制則側重于點燈,即告知資源可用;

沒有等待線程的解鎖或激發條件都是沒有意義的,而沒有等待燈亮的線程的點燈操作則有效,且能保持 燈亮狀態。當然,這樣的操作原語也意味著更多的開銷。

信號燈的應用除了燈亮/燈滅這種二元燈以外,也可以采用大于1的燈數,以表示資源數大于1,這時可以稱之為多元燈。

1. 創建和 注銷

POSIX信號燈標準定義了有名信號燈和無名信號燈兩種,但LinuxThreads的實現僅有無名燈,同時有名燈除了總是可用于多進程之間以外,在使用上與無名燈并沒有很大的區別,因此下面僅就無名燈進行討論。

int sem_init(sem_t *sem, int pshared, unsigned int value)

這是創建信號燈的API,其中value為信號燈的初值,pshared表示是否為多進程共享而不僅僅是用于一個進程。LinuxThreads沒有實現 多進程共享信號燈,因此所有非0值的pshared輸入都將使sem_init()返回-1,且置errno為ENOSYS。初始化好的信號燈由sem變 量表征,用于以下點燈、滅燈操作。

int sem_destroy(sem_t * sem)

被注銷的信號燈sem要求已沒有線程在等待該信號燈,否則返回-1,且置errno為EBUSY。除此之外,LinuxThreads的信號燈 注銷函數不做其他動作。

sem_destroy destroys a semaphore object, freeing the resources it? might? hold.? No? threads? should? be? waiting? on? the

semaphore? at? the? time? sem_destroy? is? called.? In? the? LinuxThreads implementation, no resources are associated with

semaphore objects, thus sem_destroy actually does nothing except checking that no thread is waiting on the semaphore.

2. 點燈和滅燈

int sem_post(sem_t * sem)

點燈操作將信號燈值原子地加1,表示增加一個可訪問的資源。

int sem_wait(sem_t * sem)

int sem_trywait(sem_t * sem)

sem_wait()為等待燈亮操作,等待燈亮(信號燈值大于0),然后將信號燈原子地減1,并返回。sem_trywait()為sem_wait()的非阻塞版,如果信號燈計數大于0,則原子地減1并返回0,否則立即返回-1,errno置為EAGAIN。

3. 獲取燈值

int sem_getvalue(sem_t * sem, int * sval)

讀取sem中的燈計數,存于*sval中,并返回0。

4. 其他

sem_wait()被實現為取消點。(取消點事什么意思???)

sem_wait is a cancellation point.

取消點的含義:

當用pthread_cancel()一個線程時,這個要求會被pending起來,當被cancel的線程走到下一個cancellation point時,線程才會被真正cancel掉。

而且在支持原子”比較且交換CAS”指令的體系結構上,sem_post()是唯一能用于異步信號處理函數的POSIX異步信號 安全的API。

On processors supporting atomiccompare-and-swap(Intel 486, Pentium and later, Alpha, PowerPC, MIPS? II,? Motorola? 68k),

the? sem_post function is async-signal safe and can therefore be called from signal handlers. This is the only thread syn-

chronization function provided by POSIX threads that is async-signal safe.

On the Intel 386 and the Sparc, the current LinuxThreads implementation of sem_post is not async-signal safe? by? lack? of

the required atomic operations.


互斥量(Mutex)


互斥量表現互斥現象的數據結構,也被當作二元信號燈。一個互斥基本上是一個多任務敏感的二元信號,它能用作同步多任務的行為,它常用作保護從中斷來的臨界段代碼并且在共享同步使用的資源。


Mutex本質上說就是一把鎖,提供對資源的獨占訪問,所以Mutex主要的作用是用于互斥。Mutex對象的值,只有0和1兩個值。這兩個值也分

別代表了Mutex的兩種狀態。值為0,

表示鎖定狀態,當前對象被鎖定,用戶進程/線程如果試圖Lock臨界資源,則進入排隊等待;值為1,表示空閑狀態,當前對象為空閑,用戶進程/線程可以

Lock臨界資源,之后Mutex值減1變為0。

Mutex可以被抽象為四個操作:

- 創建 Create

- 加鎖 Lock

- 解鎖 Unlock

- 銷毀 Destroy

Mutex被創建時可以有初始值,表示Mutex被創建后,是鎖定狀態還是空閑狀態。在同一個線程中,為了防止死鎖,系統不允許連續兩次對Mutex加鎖(系統一般會在第二次調用立刻返回)。也就是說,加鎖和解鎖這兩個對應的操作,需要在同一個線程中完成。

不同操作系統中提供的Mutex函數:

動作\系統Win32LinyxSolaris

創建CreateMutexpthread_mutex_initmutex_init

加鎖WaitForSingleObjectpthread_mutex_lockmutex_lock

解鎖ReleaseMutexpthread_mutex_unlockmutex_unlock

銷毀CloseHandlepthread_mutex_destroymutex_destroy



信號量

信號量(Semaphore),有時被稱為信號燈,是在多線程環境下使用的一種設施, 它負責協調各個線程, 以保證它們能夠正確、合理的使用公共資源。

信號量可以分為幾類:

2 二進制信號量(binary semaphore):只允許信號量取0或1值,其同時只能被一個線程獲取。

2 整型信號量(integer semaphore):信號量取值是整數,它可以被多個線程同時獲得,直到信號量的值變為0。

2 記錄型信號量(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引用的是初始創建的信號量。

動作\系統Win32POSIX

創建CreateSemaphoresem_init

等待WaitForSingleObjectsem _wait

釋放ReleaseMutexsem _post

試圖等待WaitForSingleObjectsem _trywait

銷毀CloseHandlesem_destroy


互斥量和信號量的區別

1. 互斥量用于線程的互斥,信號量用于線程的同步。

這是互斥量和信號量的根本區別,也就是互斥和同步之間的區別。

互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。

同步:是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源

2. 互斥量值只能為0/1,信號量值可以為非負整數。

也就是說,一個互斥量只能用于一個資源的互斥訪問,它不能實現多個資源的多線程互斥問題。信號量可以實現多個同類資源的多線程互斥和同步。當信號量為單值信號量是,也可以完成一個資源的互斥訪問。

3.互斥量的加鎖和解鎖必須由同一線程分別對應使用,信號量可以由一個線程釋放,另一個線程得到。


轉自:http://www.blogjava.net/fhtdy2004/archive/2009/07/05/285519.html

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容

  • 信號量與普通整型變量的區別: ①信號量(semaphore)是非負整型變量,除了初始化之外,它只能通過兩個標準原子...
    北風知我意閱讀 1,877評論 0 3
  • 本文轉載自信號量與互斥鎖,如有侵權,請及時聯系博主刪除。 1. 信號量與普通整型變量的區別: ①信號量(semap...
    GLGeek閱讀 1,258評論 0 1
  • Q:為什么出現多線程? A:為了實現同時干多件事的需求(并發),同時進行著下載和頁面UI刷新。對于處理器,為每個線...
    幸福相依閱讀 1,605評論 0 2
  • 1 臨界區 1.1簡介 在早期計算機系統中,只有一個任務進程在執行,并不存在資源的共享與競爭。隨著技術和需求的飛速...
    Fly晴天里Fly閱讀 9,057評論 2 13
  • 01 前幾天看到@粽粽粽粽粽粽粽的一條微博“你和你男朋友因為什么奇怪的理由吵過架?” 熱評很搞笑,截幾條給你們感受...
    愛晚睡閱讀 497評論 0 2