有了互斥鎖词爬,為什么還要條件變量料祠?

為了解決這個問題骆捧,首先要非常深入了解每一個概念:

1. 互斥鎖(mutual exclusive lock variable / mutex )

互斥量(mutex)從本質(zhì)上說是一把鎖,在訪問共享資源前對互斥量進行加鎖髓绽,在訪問完成后釋放互斥量上的鎖敛苇。對互斥量進行加鎖以后,任何其他試圖再次對互斥鎖加鎖的線程將會阻塞直到當前線程釋放該互斥鎖顺呕。如果釋放互斥鎖時有多個線程阻塞枫攀,所有在該互斥鎖上的阻塞線程都會變成可運行狀態(tài),第一個變?yōu)檫\行狀態(tài)的線程可以對互斥鎖加鎖株茶,其他線程將會看到互斥鎖依然被鎖住来涨,只能回去再次等待它重新變?yōu)榭捎谩?/strong>

2. 條件變量

條件變量(cond)是在多線程程序中用來實現(xiàn)"等待--》喚醒"邏輯常用的方法。條件變量利用線程間共享的全局變量進行同步的一種機制启盛,主要包括兩個動作:一個線程等待"條件變量的條件成立"而掛起蹦掐;另一個線程使“條件成立”。為了防止競爭僵闯,條件變量的使用總是和一個互斥鎖結(jié)合在一起卧抗。線程在改變條件狀態(tài)前必須首先鎖住互斥量,函數(shù)pthread_cond_wait把自己放到等待條件的線程列表上鳖粟,然后對互斥鎖解鎖(這兩個操作是原子操作)社裆。在函數(shù)返回時,互斥量再次被鎖住向图。

那為什么有互斥鎖泳秀,還需要條件變量?

因為:互斥鎖和條件變量所解決的张漂,是不同的問題晶默,不同的場景。

互斥鎖解決的是在 shared memory space 模型下航攒,多個線程對同一個全局變量的訪問的競爭問題磺陡。由于寫操作的非原子性(從內(nèi)存中讀進寄存器,修改漠畜,如果其他線程完成了對這個變量的修改币他,則舊的修改就被覆蓋,等等問題)憔狞,必須保證同一時間只有一個線程在進行寫操作蝴悉。這就涉及到了互斥鎖,將臨界區(qū)的操作鎖起來瘾敢,保證只有一個線程在進行操作拍冠。多個線程在等待同一把鎖的時候尿这,按照 FIFO 組織隊列,當鎖被釋放時庆杜,隊頭線程獲得鎖(由操作系統(tǒng)管理射众,具體不表)。沒有獲得鎖的線程繼續(xù)被 block晃财,換言之叨橱,它們是因為沒有獲得鎖而被 block

假如我們沒有“條件變量”這個概念断盛,如果一個線程要等待某個“自定義的條件”滿足而繼續(xù)執(zhí)行罗洗,而這個條件只能由另一個線程來滿足,比如 T1不斷給一個全局變量 x +1钢猛, T2檢測到x 大于100時伙菜,將x 置0,如果我們沒有條件變量命迈,則只通過互斥鎖則可以有如下實現(xiàn):

/* 
 * Assume we have global variables:
 * int iCount == 0;
 * pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
 */

//thread 1:

while(true)
{
    pthread_mutex_lock(&mutex);
    iCount++;
    pthread_mutex_unlock(&mutex);
}


//thread 2:
while(true)
{
    pthread_mutex_lock(&mutex);
    if(iCount >= 100)
    {
        iCount = 0;
    }
    pthread_mutex_unlock(&mutex);

}

這種實現(xiàn)下仇让,就算 lock 空閑,thread2需要不斷重復<加鎖躺翻,判斷丧叽,解鎖>這個流程,會給系統(tǒng)帶來不必要的開銷公你。有沒有一種辦法讓 thread2先被 block踊淳,等條件滿足的時候再喚醒 thread2?這樣 thread2 就不用不斷進行重復的加解鎖操作了陕靠?這就要用到條件變量了:


//thread1 :
while(true)
{
    pthread_mutex_lock(&mutex);
    iCount++;
    pthread_mutex_unlock(&mutex);

    pthread_mutex_lock(&mutex);
    if(iCount >= 100)
    {
        pthread_cond_signal(&cond);
    }
    pthread_mutex_unlock(&mutex);
}

//thread2:
while(1)
{
    pthread_mutex_lock(&mutex);
    while(iCount < 100)
    {
        pthread_cond_wait(&cond, &mutex);
    }
    printf("iCount >= 100\r\n");
    iCount = 0;
    pthread_mutex_unlock(&mutex);
}

需要注意的是迂尝,條件變量需要配合互斥鎖來使用:
為什么要與pthread_mutex 一起使用呢? 這是為了應(yīng)對 線程1在調(diào)用pthread_cond_wait()但線程1還沒有進入wait cond的狀態(tài)的時候剪芥,此時線程2調(diào)用了 cond_singal 的情況垄开。 如果不用mutex鎖的話,這個cond_singal就丟失了税肪。加了鎖的情況是溉躲,線程2必須等到 mutex 被釋放(也就是 pthread_cod_wait() 釋放鎖并進入wait_cond狀態(tài) ,此時線程2上鎖) 的時候才能調(diào)用cond_singal.

簡而言之就是益兄,在thread 1 call pthread_cond_wait() 的時刻到 thread 1真正進入 wait 狀態(tài)時锻梳,是存在著時間差的。如果在這段時間差內(nèi) thread2 調(diào)用了 pthread_cond_signal() 那這個 signal 信號就丟失了净捅。給 wait 加鎖可以防止同時有另一個線程在 signal疑枯。

(好像還有其他原因,有空補蛔六。)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荆永,一起剝皮案震驚了整個濱河市废亭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌具钥,老刑警劉巖滔以,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異氓拼,居然都是意外死亡,警方通過查閱死者的電腦和手機抵碟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門桃漾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拟逮,你說我怎么就攤上這事撬统。” “怎么了敦迄?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵恋追,是天一觀的道長。 經(jīng)常有香客問我罚屋,道長苦囱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任脾猛,我火速辦了婚禮撕彤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘猛拴。我一直安慰自己羹铅,他們只是感情好,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布愉昆。 她就那樣靜靜地躺著职员,像睡著了一般。 火紅的嫁衣襯著肌膚如雪跛溉。 梳的紋絲不亂的頭發(fā)上焊切,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天,我揣著相機與錄音芳室,去河邊找鬼蛛蒙。 笑死,一個胖子當著我的面吹牛渤愁,可吹牛的內(nèi)容都是我干的牵祟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼抖格,長吁一口氣:“原來是場噩夢啊……” “哼诺苹!你這毒婦竟也來了咕晋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤收奔,失蹤者是張志新(化名)和其女友劉穎掌呜,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坪哄,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡质蕉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了翩肌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片模暗。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖念祭,靈堂內(nèi)的尸體忽然破棺而出兑宇,到底是詐尸還是另有隱情,我是刑警寧澤粱坤,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布隶糕,位于F島的核電站,受9級特大地震影響站玄,放射性物質(zhì)發(fā)生泄漏枚驻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一株旷、第九天 我趴在偏房一處隱蔽的房頂上張望测秸。 院中可真熱鬧,春花似錦灾常、人聲如沸霎冯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沈撞。三九已至,卻和暖如春雕什,著一層夾襖步出監(jiān)牢的瞬間缠俺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工贷岸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留壹士,地道東北人。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓偿警,卻偏偏與公主長得像躏救,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 前言 在多線程開發(fā)中盒使,常會遇到多個線程訪問修改數(shù)據(jù)崩掘。為了防止數(shù)據(jù)不一致或數(shù)據(jù)污染,通常采用加鎖機制來保證線程安全少办。...
    趙夢楠閱讀 954評論 0 5
  • 引用自多線程編程指南應(yīng)用程序里面多個線程的存在引發(fā)了多個執(zhí)行線程安全訪問資源的潛在問題苞慢。兩個線程同時修改同一資源有...
    Mitchell閱讀 1,998評論 1 7
  • linux線程同步 信號燈:與互斥鎖和條件變量的主要不同在于"燈"的概念,燈亮則意味著資源可用英妓,燈滅則意味著不可用...
    鮑陳飛閱讀 690評論 0 2
  • 簡介 線程創(chuàng)建 線程屬性設(shè)置 線程參數(shù)傳遞 線程優(yōu)先級 線程的數(shù)據(jù)處理 線程的分離狀態(tài) 互斥鎖 信號量 一 線程創(chuàng)...
    第八區(qū)閱讀 8,567評論 1 6
  • 成功的路挽放,不怕萬人阻擋,只怕自己投降蔓纠;成長的帆辑畦,不怕狂風巨浪,只怕自己沒膽量贺纲!有路,就大膽去走褪测;有夢猴誊,就大膽飛翔。...
    安全保衛(wèi)處閱讀 294評論 0 0