條件變量(Condition Variable)詳解

轉載于:http://blog.csdn.net/erickhuang1989/article/details/8754357

條件變量(Condtion Variable)是在多線程程序中用來實現“等待->喚醒”邏輯常用的方法。舉個簡單的例子,應用程序A中包含兩個線程t1和t2。t1需要在bool變量test_cond為true時才能繼續執行,而test_cond的值是由t2來改變的,這種情況下,如何來寫程序呢?可供選擇的方案有兩種:

  • 第一種是t1定時的去輪詢變量test_cond,如果test_cond為false,則繼續休眠;如果test_cond為true,則開始執行。
  • 第二種就是上面提到的條件變量,t1在test_cond為false時調用cond_wait進行等待,t2在改變test_cond的值后,調用cond_signal,喚醒在等待中的t1,告訴t1 test_cond的值變了,這樣t1便可繼續往下執行。

    ??????很明顯,上面兩種方案中,第二種方案是比較優的。在第一種方案中,在每次輪詢時,如果t1休眠的時間比較短,會導致cpu浪費很厲害;如果t1休眠的時間比較長,又會導致應用邏輯處理不夠及時,致使應用程序性能下降。第二種方案就是為了解決輪詢的弊端而生的。然而條件變量在使用的過程中,比較容易出錯,如何用得不正確的話,會適得其反的,接下來,我將詳細分析如何來使用條件變量,希望能夠給在使用條件變量過程中遇到問題的朋友有所幫助。 ??????在開始介紹之前,需要說明一下,在接下來的介紹中,需要用到互斥鎖和條件變量相關的內容,在這里我以Linux下的pthread_mutex_t為互斥鎖類型,pthread_cond_t為條件變量類型來進行介紹,對pthread不熟的朋友,可以參考一下linux下的manual。 ??????1. 下面是把剛開始舉的例子翻譯后的程序:

    1
    2
    3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
    pthread_mutex_t mutex; ///< 互斥鎖 pthread_cond_t cond; ///< 條件變量 bool test_cond = false; /// TODO 初始化mutex和cond ? /// thread 1: pthread_mutex_lock(&mutex); ///< 1 while (!test_cond) { pthread_cond_wait(&cond, &mutex); ///< 2,3 } pthread_mutex_unlock(&mutex); ///< 4 RunThread1Func(); ? /// thread 2: pthread_mutex_lock(&mutex); ///< 5 test_cond = true; pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); ///< 6 ? /// TODO 銷毀mutex和cond

    ??????通過上面的例子,下面我來介紹一下條件變量在使用過程中需要注意的幾點(也是比較容易出錯的): ??????(1)條件變量的使用過程中,最為關鍵的一點是互斥鎖的使用。細心的朋友應該發現了,我在上面的例子中標了1、2、3、4、5、6個標號。在這里1、4、5、6都是正常的lock/unlock,2、3是需要特別說明的。2是進入pthread_cond_wait后的,pthread_cond_wait調的pthread_mutex_unlock,這樣做的目的是為了保證在thread1阻塞wait后,thread2獲取同一把鎖mutex的時候,能夠正常獲取(即5,6)。3是thread1被喚醒后,要退出pthead_cond_wait之前,pthread_cond_wait調的pthread_mutex_lock,這樣做的目的是為了把mutex的控制權還給調用pthread_cond_wait的線程(即thread1)。整理一下基本的時序為:

    1
    2
    3
    thread 1 lock->thread 1 wait-> thread 1 unlock(in wait) ->thread 2 lock->thread 2 signal->thread 2 unlock ->thread 1 lock(in wait)->thread 1 unlock

    ??????(2)條件變量使用的過程中,通常會加一個bool或者int的值test_cond來配合使用。這里需要注意的一點是一定要在signal之前來改變test_cond,這樣才能保證wait的線程被喚醒后,能夠取到正確的test_cond的值,否則后果是不可預測的。

轉載于:https://www.cnblogs.com/baiduboy/p/7365736.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371485.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371485.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371485.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++中的深拷貝和淺拷貝 QT中的深拷貝,淺拷貝和隱式共享

下面是C中定義的深&#xff0c;淺拷貝 當用一個已初始化過了的自定義類類型對象去初始化另一個新構造的對象的時候&#xff0c;拷貝構造函數就會被自動調用。也就是說&#xff0c;當類的對象需要拷貝時&#xff0c;拷貝構造函數將會被調用。以下情況都會調用拷貝構造函數&#…

使用PowerMock模擬構造函數

我認為&#xff0c;依賴項注入的主要好處之一是可以將模擬和/或存根對象注入代碼中&#xff0c;以提高可測試性&#xff0c;增加測試覆蓋率并編寫更好&#xff0c;更有意義的測試。 但是&#xff0c;有時候您會遇到一些不使用依賴注入的傳統代碼&#xff0c;而是通過組合而不是…

Brackets (區間DP)

個人心得&#xff1a;今天就做了這些區間DP&#xff0c;這一題開始想用最長子序列那些套路的&#xff0c;后面發現不滿足無后效性的問題&#xff0c;即&#xff08;&#xff0c;&#xff09;的配對 對結果有一定的影響&#xff0c;后面想著就用上一題的思想就慢慢的從小一步一步…

android生成aar無效,android studio生成aar包并在其他工程引用aar包的方法

1.aar包是android studio下打包android工程中src、res、lib后生成的aar文件&#xff0c;aar包導入其他android studio 工程后&#xff0c;其他工程可以方便引用源碼和資源文件2.生成aar包步驟&#xff1a;①.用android studio打開一個工程&#xff0c;然后新建一個Module&#…

《劍指offer》— JavaScript(3)從尾到頭打印鏈表

從尾到頭打印鏈表 題目描述 輸入一個鏈表&#xff0c;從尾到頭打印鏈表每個節點的值。 實現代碼 /*function ListNode(x){this.val x;this.next null; }*/ function printListFromTailToHead(head) {var res[];while(head){res.unshift(head.val);headhead.next;}return res;…

JUnit測試Spring Service和DAO(帶有內存數據庫)

這篇文章描述了如何為Spring Web Application的Services和DAO實現JUnit測試。 它建立在Spring MVC-Service-DAO-Persistence Architecture Example的基礎上 。 從Github的Spring-Web-JPA-Testing目錄中可以找到該示例。 提醒 測試裝置 –固定狀態&#xff0c;用作運行測試的基…

c# 正則獲取html標簽內容,c# – 使用正則表達式在多個HTML標記之間獲取文本

使用正則表達式,我希望能夠在多個DIV標記之間獲取文本.例如,以下內容&#xff1a;first html taganother tag輸出&#xff1a;first html taganother tag我使用的正則表達式模式只匹配我的最后一個div標簽并錯過了第一個.碼&#xff1a;static void Main(string[] args){string…

Android之外部存儲(SD卡)

*手機的外部存儲空間&#xff0c;這個我們可以理解成電腦的外接移動硬盤&#xff0c;U盤也行。所有的Android設備都有兩個文件存儲區域&#xff1a;“內部”和“外部”存儲器。這兩個名稱來自早期的Android&#xff0c;當時大多數設備都提供內置的固定的內存&#xff08;內置存…

通用并發對象池

在本文中&#xff0c;我們將介紹如何在Java中創建對象池。 近年來&#xff0c;JVM的性能成倍增加&#xff0c;大多數類型的對象幾乎都變得多余&#xff0c;從而提高了對象池的性能。 從本質上講&#xff0c;對象的創建不再像以前那樣昂貴。 但是&#xff0c;有些對象在創建時肯…

圓周率的代碼表示,以及對其的理解。

轉載的簡書&#xff0c;for 記錄以及記憶。 http://www.jianshu.com/p/7208e4a58310 Thanks again&#xff01; 轉載于:https://www.cnblogs.com/xiapeng0701/p/7538281.html

華為NOVa8Pr0是用鴻蒙系統嗎,華為Nova8即將發布,采用麒麟芯片,高端平板適配鴻蒙系統...

大家好&#xff0c;我是老孫自從華為Mate40系列發布后&#xff0c;下一步新機動態備受外界關注&#xff0c;華為究竟會不會繼續生產手機呢&#xff1f;答案是肯定&#xff0c;華為Nova8系列將于本月發布&#xff0c;華為P50系列也在積極籌備&#xff0c;而且都少不了麒麟芯片&a…

使用路標的Scala和Java的Twitter REST API

如果您已閱讀此博客上的其他文章&#xff0c;您可能會知道我喜歡創建各種數據集的可視化。 我剛剛開始一個小項目&#xff0c;在這里我想可視化來自Twitter的一些數據。 為此&#xff0c;我想直接從Twitter檢索有關關注者的信息和個人資料信息。 我實際上開始尋找一組所有推特帳…

大話設計模式讀書筆記--11.抽象工廠模式

定義 抽象工廠模式定義: 提供一個創建一系列相關或相關依賴對象的接口,而無需指定他們具體的類 抽象工廠模式通常是用于創建一族產品&#xff0c;并且這族產品分不同的等級&#xff1b;不同的具體工廠類生產不同等級的一族產品 比如下圖(來源于網絡) 兩廂車和三廂車稱為兩個不同…

在線壓縮html,JS代碼壓縮 - javascript代碼壓縮 - jsmin在線js壓縮工具

輸入代碼&#xff1a;// is.js// (c) 2001 Douglas Crockford// 2001 June 3// The -is- object is used to identify the browser. Every browser edition// identifies itself, but there is no standard way of doing it, and some of// the identification is deceptive. T…

Primefaces dataTable設置某個cell的樣式問題

設置primefaces dataTable的源網段列的Cell可以編輯&#xff0c;當回車鍵保存時&#xff0c;判斷是否輸入的網段合法&#xff0c;如果不合法就顯示警告信息&#xff0c;并將這個不合法的數據用紅色表示。問題是&#xff0c;怎么給這一個cell設定樣式。通過給標簽設定ID然后在后…

鴨子在Java中打字? 好吧,不完全是

根據維基百科&#xff0c;鴨子的打字是&#xff1a; 動態類型的類型&#xff0c;其中對象的方法和屬性確定有效的語義&#xff0c;而不是其從特定類或特定接口的實現繼承 用簡單的話 當我看到一只鳥走路像鴨子&#xff0c;游泳像鴨子&#xff0c;嘎嘎像鴨子一樣時&#xff0c…

前端學習路線

第一部分 HTML 第一章 職業規劃和前景 職業方向規劃定位&#xff1a; web前端開發工程師 web網站架構師 自己創業 轉崗管理或其他 web前端開發的前景展望&#xff1a; 未來IT行業企業需求最多的人才 結合最新的html5搶占移動端的市場 自己創業做老板 隨著互聯網的普及we…

p1164【立方體求和】

題目&#xff1a; SubRaY有一天得到一塊西瓜,是長方體形的....SubRaY發現這塊西瓜長m厘米,寬n厘米,高h厘米.他發現如果把這塊西瓜平均地分成m*n*h塊1立方厘米的小正方體,那么每一小塊都會有一個營養值(可能為負,因為西瓜是有可能壞掉的,但是絕對值不超過200).現在SubRaY決定從這…

html生成自定義表格,自定義js的表格插件

場景&#xff1a;指定元素&#xff0c;生成自定義表格。目的&#xff1a;了解js的插件開發。html代碼&#xff1a;自定義表格插件var test new MyTable({elid:"mytable",//定義哪個div要生成表單thead:{//指定列名name:"姓名",age:"年齡",addr:…

使用JBehave,Gradle和Jenkins的行為驅動開發(BDD)

行為驅動開發 &#xff08;BDD&#xff09;是一個協作過程 &#xff0c;產品負責人&#xff0c;開發人員和測試人員可以合作交付可為企業帶來價值的軟件。 BDD是 測試驅動開發 &#xff08;TDD&#xff09; 的合理下一步 。 行為驅動的發展 本質上&#xff0c;BDD是一種交付…