[英]Condition Variable - Wait/Notify Race Condition
我將首先介紹一些代碼,因為解釋更容易。 假設互斥鎖正確地與條件變量一起使用以保持簡單:
// Thread 1
while(1)
{
conditionVariable.wait();
// Do some work
}
// Thread 2
while(1)
{
// Do some work
conditionVariable.notify_one();
}
// Thread 3
while(1)
{
// Do some work
conditionVariable.notify_one();
}
我想要實現的是線程1保證在線程2或線程3通知時等待條件變量。 正如代碼所代表的那樣, notify_one()
和wait()
之間存在很大的差距,其形式是由注釋標記的其他代碼。 這個差距意味着有時在調用wait()
之前調用notify_one()
wait()
。
經過一番思考后,似乎最接近我的是在notify_one()
之前和wait()
之前(在線程1的循環開始時wait()
使用某種形式的互斥。 但是,無論如何完成,在互斥和wait()
之間仍然存在一個小的間隙(1行代碼wait()
,允許線程2和3在線程1調用wait()
之前調用notify_one()
wait()
。 這不太可能,但可能。
我還考慮過使用wait()
謂詞來標記一個允許其他線程通知的布爾值。 我想這可行,因為wait()
是原子的,但我想知道是否有更好的方法。 也許我接近這個錯誤。
總結:在允許線程2和3通知之前,如何確保線程1正在等待?
簡而言之:將條件變量視為一種方法,通知其他線程某些事情發生了變化,而不僅僅是作為信號。
為了做到這一點,條件變量應該伴隨一個條件(簡單的例子:一個整數遞增),可以由接收線程處理。
現在,為了解決您的問題,線程1可以使用帶有ready布爾值的條件變量來在其准備接收條件變量信號時發信號通知其他線程,但是您最好先檢查原始條件變量是否可以按照描述使用這里。
基於問題的偽代碼(仍然需要正確鎖定conditionVariable):
// Thread 1
while(1)
{
lockReady();
ready = true;
unlockReady();
readyCV.notify_one();
conditionVariable.wait();
// Do some work
}
// Thread 2
while(1)
{
lockReady();
while (! ready) readyCV.wait();
ready = false;
unlockReady();
// Do some work
conditionVariable.notify_one();
}
// Thread 3
while(1)
{
lockReady();
while (! ready) readyCV.wait();
ready = false;
unlockReady();
// Do some work
conditionVariable.notify_one();
}
另見我之前的回答
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.