秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量
前面《秒殺多線程第四篇一個(gè)經(jīng)典的多線程同步問(wèn)題》提出了一個(gè)經(jīng)典的多線程同步互斥問(wèn)題,這個(gè)問(wèn)題包括了主線程與子線程的同步,子線程間的互斥,是一道非常經(jīng)典的多線程同步互斥問(wèn)題范例,后面分別用了四篇
《秒殺多線程第五篇經(jīng)典線程同步關(guān)鍵段CS》
《秒殺多線程第六篇經(jīng)典線程同步事件Event》
《秒殺多線程第七篇經(jīng)典線程同步互斥量Mutex》
《秒殺多線程第八篇經(jīng)典線程同步信號(hào)量Semaphore》
來(lái)詳細(xì)介紹常用的線程同步互斥機(jī)制——關(guān)鍵段、事件、互斥量、信號(hào)量。下面對(duì)它們作個(gè)總結(jié),幫助大家梳理各個(gè)知識(shí)點(diǎn)。
?
首先來(lái)看下關(guān)于線程同步互斥的概念性的知識(shí),相信大家通過(guò)前面的文章,已經(jīng)對(duì)線程同步互斥有一定的認(rèn)識(shí)了,也能模糊的說(shuō)出線程同步互斥的各種概念性知識(shí),下面再列出從《計(jì)算機(jī)操作系統(tǒng)》一書(shū)中選取的一些關(guān)于線程同步互斥的描述。相信先有個(gè)初步而模糊的印象再看下權(quán)威的定義,應(yīng)該會(huì)記憶的特別深刻。
?
1.線程(進(jìn)程)同步的主要任務(wù)
答:在引入多線程后,由于線程執(zhí)行的異步性,會(huì)給系統(tǒng)造成混亂,特別是在急用臨界資源時(shí),如多個(gè)線程急用同一臺(tái)打印機(jī),會(huì)使打印結(jié)果交織在一起,難于區(qū)分。當(dāng)多個(gè)線程急用共享變量,表格,鏈表時(shí),可能會(huì)導(dǎo)致數(shù)據(jù)處理出錯(cuò),因此線程同步的主要任務(wù)是使并發(fā)執(zhí)行的各線程之間能夠有效的共享資源和相互合作,從而使程序的執(zhí)行具有可再現(xiàn)性。
?
2.線程(進(jìn)程)之間的制約關(guān)系?
當(dāng)線程并發(fā)執(zhí)行時(shí),由于資源共享和線程協(xié)作,使用線程之間會(huì)存在以下兩種制約關(guān)系。
(1).間接相互制約。一個(gè)系統(tǒng)中的多個(gè)線程必然要共享某種系統(tǒng)資源,如共享CPU,共享I/O設(shè)備,所謂間接相互制約即源于這種資源共享,打印機(jī)就是最好的例子,線程A在使用打印機(jī)時(shí),其它線程都要等待。
(2).直接相互制約。這種制約主要是因?yàn)榫€程之間的合作,如有線程A將計(jì)算結(jié)果提供給線程B作進(jìn)一步處理,那么線程B在線程A將數(shù)據(jù)送達(dá)之前都將處于阻塞狀態(tài)。
間接相互制約可以稱(chēng)為互斥,直接相互制約可以稱(chēng)為同步,對(duì)于互斥可以這樣理解,線程A和線程B互斥訪問(wèn)某個(gè)資源則它們之間就會(huì)產(chǎn)個(gè)順序問(wèn)題——要么線程A等待線程B操作完畢,要么線程B等待線程操作完畢,這其實(shí)就是線程的同步了。因此同步包括互斥,互斥其實(shí)是一種特殊的同步。
?
3.臨界資源和臨界區(qū)
在一段時(shí)間內(nèi)只允許一個(gè)線程訪問(wèn)的資源就稱(chēng)為臨界資源或獨(dú)占資源,計(jì)算機(jī)中大多數(shù)物理設(shè)備,進(jìn)程中的共享變量等待都是臨界資源,它們要求被互斥的訪問(wèn)。每個(gè)進(jìn)程中訪問(wèn)臨界資源的代碼稱(chēng)為臨界區(qū)
?
看完概念性知識(shí),下面用幾個(gè)表格來(lái)幫助大家更好的記憶和運(yùn)用多線程同步互斥的四個(gè)實(shí)現(xiàn)方法——關(guān)鍵段、事件、互斥量、信號(hào)量。
?
關(guān)鍵段CS與互斥量Mutex
| ? | 創(chuàng)建或初始化 | 銷(xiāo)毀 | 進(jìn)入互斥區(qū)域 | 離開(kāi)互斥區(qū)域 |
| 關(guān)鍵段CS | Initialize- CriticalSection | Delete- CriticalSection | Enter- CriticalSection | Leave- CriticalSection |
| 互斥量Mutex | CreateMutex | CloseHandle | 等待系列函數(shù)如WaitForSingleObject | ReleaseMutex |
關(guān)鍵段與互斥量都有“線程所有權(quán)”概念,可以將“線程所有權(quán)”理解成旅館的房卡,在旅館前臺(tái)登記名字擁有房卡后是可以多次進(jìn)出房間的,其它人則無(wú)法進(jìn)入直到你交出房卡。每個(gè)線程必須先通過(guò)EnterCriticalSection或WaitForSingleObject來(lái)嘗試獲得“線程所有權(quán)”才能調(diào)用LeaveCriticalSection或ReleaseMutex。否則會(huì)調(diào)用失敗,這就相當(dāng)于偽造房卡去辦理退房手續(xù)——由于登記本上沒(méi)有你的名字所以會(huì)被拒絕。
互斥量能很好的處理“遺棄”情況,因此在多進(jìn)程之間可以放心的使用。
?
事件Event
| ? | 創(chuàng)建 | 銷(xiāo)毀 | 使事件觸發(fā) | 使事件未觸發(fā) |
| 事件Event | CreateEvent | CloseHandle | SetEvent | ResetEvent |
注意事件的手動(dòng)置位和自動(dòng)置位要分清楚,不要混淆了。
?
信號(hào)量Semaphore
| ? | 創(chuàng)建 | 銷(xiāo)毀 | 遞減計(jì)數(shù) | 遞增計(jì)數(shù) |
| 信號(hào)量 Semaphore | Create- Semaphore | CloseHandle | 等待系列函數(shù)如WaitForSingleObject | Release- Semaphore |
信號(hào)量在計(jì)數(shù)大于0時(shí)表示觸發(fā)狀態(tài),調(diào)用WaitForSingleObject不會(huì)阻塞,等于0表示未觸發(fā)狀態(tài),調(diào)用WaitForSingleObject會(huì)阻塞直到有其它線程遞增了計(jì)數(shù)。
?
注意:互斥量,事件,信號(hào)量都是內(nèi)核對(duì)象,可以跨進(jìn)程使用(通過(guò)OpenMutex,OpenEvent,OpenSemaphore)。不過(guò)為什么只有互斥量能解決“遺棄”情況了,請(qǐng)看《秒殺多線程第十五篇 關(guān)鍵段,事件,互斥量,信號(hào)量的“遺棄”問(wèn)題》。
?
呵呵^_^,本系列一共使用了六篇文章來(lái)講解了上面三個(gè)表格,如果讀者能輕松寫(xiě)出這個(gè)表格并能解釋下各函數(shù)的用法,那么對(duì)多線程的同步互斥問(wèn)題也就有了良好的基礎(chǔ)。
?
通過(guò)經(jīng)典線程同步問(wèn)題的學(xué)習(xí),我們已經(jīng)初步練好了解決多線程同步互斥的各種“招式”,下面再通過(guò)學(xué)習(xí)二個(gè)著名的實(shí)例《秒殺多線程第十篇 生產(chǎn)者消費(fèi)者問(wèn)題》和《秒殺多線程第十一篇 讀者寫(xiě)者問(wèn)題》來(lái)使我們?cè)诮鉀Q多線程同步時(shí)更加熟練。
總結(jié)
以上是生活随笔為你收集整理的秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 秒杀多线程第七篇 经典线程同步 互斥量M
- 下一篇: 秒杀多线程第八篇 经典线程同步 信号量S