秒杀多线程第十五篇 关键段,事件,互斥量,信号量的“遗弃”问题
秒殺多線程第十五篇 關(guān)鍵段,事件,互斥量,信號(hào)量的“遺棄”問(wèn)題
在《秒殺多線程第九篇 經(jīng)典線程同步總結(jié) 關(guān)鍵段 事件 互斥量 信號(hào)量》中對(duì)經(jīng)典多線程同步互斥問(wèn)題進(jìn)行了回顧和總結(jié),這篇文章對(duì)Windows系統(tǒng)下常用的線程同步互斥機(jī)制——關(guān)鍵段、事件、互斥量、信號(hào)量進(jìn)行了總結(jié)。有網(wǎng)友問(wèn)到互斥量能處理“遺棄”問(wèn)題,事件和信號(hào)量是否也能處理“遺棄”問(wèn)題。因此本文將對(duì)事件和信號(hào)量作個(gè)試驗(yàn),看看事件和信號(hào)量能否處理“遺棄”問(wèn)題。
?
一.什么是“遺棄”問(wèn)題
在《秒殺多線程第七篇 經(jīng)典線程同步 互斥量Mutex》講到了互斥量能處理“遺棄”問(wèn)題,下面引用原文:
互斥量常用于多進(jìn)程之間的線程互斥,所以它比關(guān)鍵段還多一個(gè)很有用的特性——“遺棄”情況的處理。比如有一個(gè)占用互斥量的線程在調(diào)用ReleaseMutex()觸發(fā)互斥量前就意外終止了(相當(dāng)于該互斥量被“遺棄”了),那么所有等待這個(gè)互斥量的線程是否會(huì)由于該互斥量無(wú)法被觸發(fā)而陷入一個(gè)無(wú)窮的等待過(guò)程中了?這顯然不合理。因?yàn)檎加媚硞€(gè)互斥量的線程既然終止了那足以證明它不再使用被該互斥量保護(hù)的資源,所以這些資源完全并且應(yīng)當(dāng)被其它線程來(lái)使用。因此在這種“遺棄”情況下,系統(tǒng)自動(dòng)把該互斥量?jī)?nèi)部的線程ID設(shè)置為0,并將它的遞歸計(jì)數(shù)器復(fù)置為0,表示這個(gè)互斥量被觸發(fā)了。然后系統(tǒng)將“公平地”選定一個(gè)等待線程來(lái)完成調(diào)度(被選中的線程的WaitForSingleObject()會(huì)返回WAIT_ABANDONED_0)。
可見(jiàn)“遺棄”問(wèn)題就是——占有某種資源的進(jìn)程意外終止后,其它等待該資源的進(jìn)程能否感知。
?
二.關(guān)鍵段的“遺棄”問(wèn)題
關(guān)鍵段在這個(gè)問(wèn)題上很簡(jiǎn)單——由于關(guān)鍵段不能跨進(jìn)程使用,所以關(guān)鍵段不需要處理“遺棄”問(wèn)題。
?
三.事件,互斥量,信號(hào)量的“遺棄”問(wèn)題
事件,互斥量,信號(hào)量都是內(nèi)核對(duì)象,可以跨進(jìn)程使用。一個(gè)進(jìn)程在創(chuàng)建一個(gè)命名的事件后,其它進(jìn)程可以調(diào)用OpenEvent()并傳入事件的名稱(chēng)來(lái)獲得這個(gè)事件的句柄。因此事件,互斥量和信號(hào)量都會(huì)遇到“遺棄”問(wèn)題。我們已經(jīng)知道互斥量能夠處理“遺棄”問(wèn)題,接下來(lái)就來(lái)看看事件和信號(hào)量是否能夠處理“遺棄”問(wèn)題。類(lèi)似于《秒殺多線程第七篇 經(jīng)典線程同步互斥量Mutex》對(duì)互斥量所做的試驗(yàn),下面也對(duì)事件和信號(hào)量作同樣的試驗(yàn):
1.?創(chuàng)建二個(gè)進(jìn)程。
2.?進(jìn)程一創(chuàng)建一個(gè)初始為未觸發(fā)的事件,然后等待按鍵,按下y則觸發(fā)事件后結(jié)束進(jìn)程,否則直接退出表示進(jìn)程一已意外終止。
3.?進(jìn)程二先獲得事件的句柄,然后調(diào)用WaitForSingleObject()等待這個(gè)事件10秒,在這10秒內(nèi)如果事件已經(jīng)觸發(fā)則輸出“已收到信號(hào)”,否則輸出“未在規(guī)定的時(shí)間內(nèi)收到信號(hào)”。如果在等待的過(guò)程中進(jìn)程一意外終止,則輸出“擁有事件的進(jìn)程意外終止”。信號(hào)量的試驗(yàn)方法類(lèi)似。
為了加強(qiáng)對(duì)比效果,將互斥量的試驗(yàn)結(jié)果先展示出來(lái)(代碼請(qǐng)參見(jiàn)《秒殺多線程第七篇經(jīng)典線程同步 互斥量Mutex》)
可以看出在第一個(gè)進(jìn)程在沒(méi)有觸發(fā)互斥量就直接退出的情況下,等待這個(gè)互斥量的第二個(gè)進(jìn)程是能夠感知進(jìn)程一所發(fā)生的意外終止的。
接下來(lái)就先完成事件的“遺棄”問(wèn)題試驗(yàn)代碼。
進(jìn)程一:
[cpp]?view plaincopy進(jìn)程二:
[cpp]?view plaincopy事件Event試驗(yàn)結(jié)果1-進(jìn)程一觸發(fā)事件后正常結(jié)束:
事件Event試驗(yàn)結(jié)果2-進(jìn)程一意外終止:
可以看出進(jìn)程二沒(méi)能感知進(jìn)程一意外終止,說(shuō)明事件不能處理“遺棄”問(wèn)題。
?
下面再來(lái)試下信號(hào)量。
信號(hào)量的“遺棄”問(wèn)題試驗(yàn)代碼:
進(jìn)程一:
[cpp]?view plaincopy進(jìn)程二:
[cpp]?view plaincopy信號(hào)量Semaphore試驗(yàn)結(jié)果1-進(jìn)程一觸發(fā)信號(hào)量后正常結(jié)束
信號(hào)量Semaphore試驗(yàn)結(jié)果2-進(jìn)程一意外終止
可以看出進(jìn)程二沒(méi)能感知進(jìn)程一意外終止,說(shuō)明信號(hào)量與事件一樣都不能處理“遺棄”問(wèn)題。
?
四.“遺棄”問(wèn)題總結(jié)
由本文所做的試驗(yàn)可知,互斥量能夠處理“遺棄”情況,事件與信號(hào)量都無(wú)法解決這一情況。
再思考下互斥量能處理“遺棄”問(wèn)題的原因,其實(shí)正是因?yàn)樗小熬€程所有權(quán)”概念。在系統(tǒng)中一旦有線程結(jié)束后,系統(tǒng)會(huì)判斷是否有互斥量被這個(gè)線程占有,如果有,系統(tǒng)會(huì)將這互斥量對(duì)象內(nèi)部的線程ID號(hào)將設(shè)置為NULL,遞歸計(jì)數(shù)設(shè)置為0,這表示該互斥量已經(jīng)不為任何線程占用,處于觸發(fā)狀態(tài)。其它等待這個(gè)互斥量的線程就能順利執(zhí)行下去了。至于線程如何獲取互斥量的“線程所有權(quán)”,MSDN上介紹為——A thread obtainsownership of a mutex either by creating it with the?bInitialOwnerparameter set to?TRUE?or by specifying its handle in a call toone of the?wait functions.
文章到這就結(jié)束了,有問(wèn)題歡迎留言或發(fā)送郵件:morewindows@126.com
?
?
?
轉(zhuǎn)載請(qǐng)標(biāo)明出處,原文地址:http://blog.csdn.net/morewindows/article/details/7823572
如果覺(jué)得本文對(duì)您有幫助,請(qǐng)點(diǎn)擊‘頂’支持一下,您的支持是我寫(xiě)作最大的動(dòng)力,謝謝。
?
?
?
最后號(hào)外一下:《白話經(jīng)典算法系列之七大排序》已經(jīng)整理出電子書(shū)形式了,歡迎大家下載,下載地址:http://download.csdn.net/detail/morewindows/4443208。
總結(jié)
以上是生活随笔為你收集整理的秒杀多线程第十五篇 关键段,事件,互斥量,信号量的“遗弃”问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 秒杀多线程第十四篇 读者写者问题继 读写
- 下一篇: 秒杀多线程第十六篇 多线程十大经典案例之