OS / Linux / pthread_cond_wait 为什么需要传递 mutex 参数?
栗子:
mutex.lock();while (判斷“條件”是否成立) {pthread_cond_wait 等待 }mutext.unlock();條件變量這個互斥鎖,不是用來保護條件變量的內(nèi)部狀態(tài)。而是用來保護外部“條件”(就是那個 while 循環(huán)中的判斷)。假如條件變量的內(nèi)部狀態(tài)需要鎖定,完全可以在內(nèi)部實現(xiàn)中維護一個鎖,沒有必要從外部傳進來。
用于判斷是否等待的“條件”,通常就是線程之間共享的某個變量值。A 線程判斷“條件”等待,會讀取共享變量。B 線程讓“條件”滿足,會修改變量。這個鎖,就是保護線程間的共享變量(“條件”),讓“條件”不會一邊修改,一邊讀取。
這把鎖還有個額外的作用。wait 函數(shù)會阻塞,將線程 A 放到阻塞隊列中。wait 函數(shù)放在鎖的 lock,unlock 內(nèi)部,也保證了線程還沒有真正放到阻塞隊列時,線程 B 不能修改“條件”后進行喚醒。這段話應(yīng)該暫時讀不懂,可回頭再看,先放在這里,不然描述就不夠準確。
不同的應(yīng)用會有不同的“條件”,在實現(xiàn)條件變量這個庫時,是沒有辦法預(yù)先知道這個“條件”究竟是什么。因此要保護“條件”,就只能讓用戶自己在庫外部分配鎖。
弄清了這個互斥鎖究竟在保護什么。這時我們才能進一步討論 pthread_cond_wait 為什么要傳入這個鎖呢?這點就跟 wait 的實現(xiàn)有關(guān)。
先來看等待線程 A 的寫法。
mutex.lock();while (判斷“條件”是否成立) {pthread_cond_wait 等待 }mutext.unlock();判斷“條件”是否成立,在 lock, unlock 之間受到保護。pthread_cond_wait 可能會阻塞,假如真的阻塞,mutex 這鎖就一直不能被釋放了。因此在 pthread_cond_wait 的實現(xiàn)內(nèi)部,在阻塞之前,必須先將鎖釋放。在喚醒的時候,再重新獲取鎖。
將 pthread_cond_wait 展開,內(nèi)部實現(xiàn)中,會有下面的過程。
做一些其它事情 mutext.unlock() 阻塞中... 喚醒 mutext.lock()假如在線程 A 中完全展開 pthread_cond_wait。
mutex.lock();while (判斷“條件”是否成立) {做一些其它事情mutext.unlock()阻塞喚醒mutext.lock() }mutext.unlock();可以看到,判斷“條件” 一直在 mutext 的 lock, unlock 之間,受到保護。
來到這里,我們總結(jié)一下。
注意上面第 2 點中,“適當時機”這個詞。假如不將這個鎖傳入 pthread_cond_wait,讓用戶自己在阻塞前先釋放鎖,是沒有辦法做到適當時機的。阻塞隊列在條件變量庫內(nèi)部維護,只有條件變量庫內(nèi)部才能控制這個時機。
wait 會阻塞,將線程 A 放到阻塞隊列中。在線程還沒有真正放到阻塞隊列時,需要一直上鎖。不然另一線程 B 修改“條件”后進行喚醒,這個線程 A 還沒有在阻塞隊列中,就不能被喚醒了。因而這把保護外部判斷“條件”的鎖,需要傳入到 wait 函數(shù)中。等將線程真正放到阻塞隊列后才能解鎖,之后線程被喚醒后再重新獲取。
線程 A 的 pthread_cond_wait 需要傳入 mutext,并且 pthread_cond_wait 一定要在 lock 和 unlock 之間。
至于線程 B, 用于修改“條件”。修改“條件” 也必須在 lock 和 unlock 之間,受互斥鎖保護。至于 pthread_cond_signal 是否在 lock 和 unlock 之間,其實是沒有關(guān)系的。但 pthread_cond_signal 必須在修改“條件”之后,不然可能 A 線程被喚醒后,條件不滿足繼續(xù)等待,這個喚醒信號就丟失了。
mutext.lock() 修改”條件“ pthread_cond_signal 喚醒 mutext.unlock()也可以將 pthread_cond_signal 移到 unlock 外部。
mutext.lock() 修改”條件“ mutext.unlock() pthread_cond_signal 喚醒條件變量等待時,那個 wait 的判斷,需要使用 while 循環(huán),而不是 if,是防止虛假喚醒。就不再一一分析了。
?
作者:黃兢成
鏈接:https://www.zhihu.com/question/24116967/answer/676751734
來源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
?
(SAW:Game Over!)
總結(jié)
以上是生活随笔為你收集整理的OS / Linux / pthread_cond_wait 为什么需要传递 mutex 参数?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OS / 进程启动过程
- 下一篇: OS / Linux / 文件描述符以及