国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網站 > 建站經驗 > 正文

淺談互斥鎖為什么還要和條件變量配合使用

2019-11-02 16:50:09
字體:
來源:轉載
供稿:網友

mutex體現的是一種競爭,我離開了,通知你進來。

cond體現的是一種協作,我準備好了,通知你開始吧。

互斥鎖一個明顯的缺點是它只有兩種狀態:鎖定和非鎖定。而條件變量通過允許線程阻塞和等待另一個線程發送信號的方法彌補了互斥鎖的不足,它常和互斥鎖一起配合使用。使用時,條件變量被用來阻塞一個線程,當條件不滿足時,線程往往解開相應的互斥鎖并等待條件發生變化。一旦其他的某個線程改變了條件變量,他將通知相應的條件變量喚醒一個或多個正被此條件變量阻塞的線程。這些線程將重新鎖定互斥鎖并重新測試條件是否滿足。一般說來,條件變量被用來進行線程間的同步。

兩個線程操作同一臨界區時,通過互斥鎖保護,若A線程已經加鎖,B線程再加鎖時候會被阻塞,直到A釋放鎖,B再獲得鎖運行,進程B必須不停的主動獲得鎖、檢查條件、釋放鎖、再獲得鎖、再檢查、再釋放,一直到滿足運行的條件的時候才可以(而此過程中其他線程一直在等待該線程的結束),這種方式是比較消耗系統的資源的。而條件變量同樣是阻塞,還需要通知才能喚醒,線程被喚醒后,它將重新檢查判斷條件是否滿足,如果還不滿足,該線程就休眠了,應該仍阻塞在這里,等待條件滿足后被喚醒,節省了線程不斷運行浪費的資源。這個過程一般用while語句實現。當線程B發現被鎖定的變量不滿足條件時會自動的釋放鎖并把自身置于等待狀態,讓出CPU的控制權給其它線程。其它線程 此時就有機會去進行操作,當修改完成后再通知那些由于條件不滿足而陷入等待狀態的線程。這是一種通知模型的同步方式,大大的節省了CPU的計算資源,減少了線程之間的競爭,而且提高了線程之間的系統工作的效率。這種同步方式就是條件變量。                                       

以上說明可能有點抽象,考慮這樣的簡單場景:通過偽代碼說明。

A線程從隊列中取元素,B線程往隊列中存放元素。不考慮免鎖的實現。需要一個mutex用來保護隊列的一致性,避免兩個線程同時操作隊列破壞數據結構。

當隊列為空的時候,A需要不斷的探測隊列狀態 :

while(1){ if(隊列為空)休眠10selse    {        加鎖        取元素        解鎖     }}

這就有一個問題,可能在剛進入休眠時,B放入元素了,但仍然需要休眠完整個10s的時間。造成不必要的延遲。當然如果不sleep,也可以,但會造成不必要的CPU開銷。使用基于條件變量的事件通知喚醒機制,就可以避免這些問題。

一旦B放入元素完成后就執行pthread_cond_signal(),當前阻塞的線程就會立即被喚醒開始干活兒。

while(1) {    pthread_mutex_lock();    pthread_cond_wait();    取元素;    pthread_mutex_unlock();}


條件變量都用互斥鎖進行保護,條件變量狀態的改變都應該先鎖住互斥鎖,pthread_cond_wait()需要傳入一個已經加鎖的互斥鎖,該函數把調用線程加入等待條件的調用列表中,然后釋放互斥鎖,在條件滿足從而離開pthread_cond_wait()時,mutex將被重新加鎖,這兩個函數是原子操作。

可以消除條件發生和線程睡眠等待條件發生間的時間間隙。其他線程在獲得互斥量之前不會察覺到這種改變,因為必須鎖定互斥量才能計算條件。

總而言之,為了避免因條件判斷語句與其后的正文或wait語句之間的間隙而產生的漏判或誤判,所以用一個mutex來保證: 對于某個cond的包括(判斷,修改)在內的任何有關操作某一時刻只有一個線程在訪問。也就是說條件變量本身就是一個競爭資源,這個資源的作用是對其后程序正文的執行權,于是用一個鎖來保護。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 天祝| 绥中县| 两当县| 宁乡县| 榆中县| 确山县| 南充市| 罗江县| 阿城市| 云南省| 潞西市| 土默特左旗| 周至县| 邓州市| 壤塘县| 始兴县| 宁乡县| 房产| 搜索| 安福县| 伊通| 沾益县| 渝北区| 阳西县| 襄汾县| 东海县| 元江| 盐边县| 台中市| 钟祥市| 甘德县| 南城县| 德州市| 百色市| 永仁县| 南阳市| 陵川县| 广安市| 栖霞市| 宜良县| 宜良县|