】條件變量(Condition Variable)詳解)
[歷史歸檔]本文原發(fā)布于 cstriker1407.info 個人博客內(nèi)容為歷史存檔僅供參考。發(fā)布時間2018-11-14 標題【轉(zhuǎn)】條件變量(Condition Variable)詳解分類編程 標簽linux·threadpthread條件變量測試筆記本文轉(zhuǎn)自《 http://www.wuzesheng.com/?p1668 》條件變量(Condtion Variable)是在多線程程序中用來實現(xiàn)“等待-喚醒”邏輯常用的方法。舉個簡單的例子應(yīng)用程序A中包含兩個線程t1和t2。t1需要在bool變量test_cond為true時才能繼續(xù)執(zhí)行而test_cond的值是由t2來改變的這種情況下如何來寫程序呢可供選擇的方案有兩種第一種是t1定時的去輪詢變量test_cond如果test_cond為false則繼續(xù)休眠如果test_cond為true則開始執(zhí)行。第二種就是上面提到的條件變量t1在test_cond為false時調(diào)用cond_wait進行等待t2在改變test_cond的值后調(diào)用cond_signal喚醒在等待中的t1告訴t1 test_cond的值變了這樣t1便可繼續(xù)往下執(zhí)行。很明顯上面兩種方案中第二種方案是比較優(yōu)的。在第一種方案中在每次輪詢時如果t1休眠的時間比較短會導(dǎo)致cpu浪費很厲害如果t1休眠的時間比較長又會導(dǎo)致應(yīng)用邏輯處理不夠及時致使應(yīng)用程序性能下降。第二種方案就是為了解決輪詢的弊端而生的。然而條件變量在使用的過程中比較容易出錯如何用得不正確的話會適得其反的接下來我將詳細分析如何來使用條件變量希望能夠給在使用條件變量過程中遇到問題的朋友有所幫助。在開始介紹之前需要說明一下在接下來的介紹中需要用到互斥鎖和條件變量相關(guān)的內(nèi)容在這里我以linux下的pthread_mutex_t為互斥鎖類型pthread_cond_t為條件變量類型來進行介紹對pthread不熟的朋友可以參考一下linux下的manual。下面是把剛開始舉的例子翻譯后的程序pthread_mutex_tmutex;/// 互斥鎖pthread_cond_tcond;/// 條件變量bool test_condfalse;/// TODO 初始化mutex和cond/// thread 1:pthread_mutex_lock(mutex);/// 1while(!test_cond){pthread_cond_wait(cond,mutex);/// 2,3}pthread_mutex_unlock(mutex);/// 4RunThread1Func();/// thread 2:pthread_mutex_lock(mutex);/// 5test_condtrue;pthread_cond_signal(cond);pthread_mutex_unlock(mutex);/// 6/// TODO 銷毀mutex和cond通過上面的例子下面我來介紹一下條件變量在使用過程中需要注意的幾點也是比較容易出錯的1條件變量的使用過程中最為關(guān)鍵的一點是互斥鎖的使用。細心的朋友應(yīng)該發(fā)現(xiàn)了我在上面的例子中標了1、2、3、4、5、6個標號。在這里1、4、5、6都是正常的lock/unlock2、3是需要特別說明的。2是進入pthread_cond_wait后的pthread_cond_wait調(diào)的pthread_mutex_unlock這樣做的目的是為了保證在thread1阻塞wait后thread2獲取同一把鎖mutex的時候能夠正常獲取即56。3是thread1被喚醒后要退出pthead_cond_wait之前pthread_cond_wait調(diào)的pthread_mutex_lock這樣做的目的是為了把mutex的控制權(quán)還給調(diào)用pthread_cond_wait的線程即thread1。整理一下基本的時序為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 unlock2條件變量使用的過程中通常會加一個bool或者int的值test_cond來配合使用。這里需要注意的一點是一定要在signal之前來改變test_cond這樣才能保證wait的線程被喚醒后能夠取到正確的test_cond的值否則后果是不可預(yù)測的。