3

我會先介紹一些代碼,因爲解釋更容易。假設互斥正確使用條件變量來保持它的簡單:條件變量 - 等待/通知競爭條件

// 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()之間有很大的差距,以其他代碼的形式標註評論。這個差距意味着有時notify_one()被調用之前有機會致電wait()

經過一番思考,似乎最接近我的是在notify_one()之前和wait()之前(在線程1的循環開始之前)使用某種形式的互斥。但是,無論如何完成,互斥和wait()之間仍然存在一小段差距(1行代碼),允許線程2和3在線程1調用wait()之前調用notify_one()。這是不可能的,但可能的。

我也考慮過使用wait()謂詞來標記一個允許其他線程通知的布爾值。我猜這會起作用,因爲wait()是原子,但我想知道是否有更好的方法。也許我錯誤地接近了這一點。

總結:如何確保線程1在允許線程2和3通知之前等待?

回答

4

簡而言之:考慮條件變量作爲一種方法來通知其他線程某些變化,而不僅僅是一個信號。

爲了做到這一點,條件變量應該伴隨一個可以由接收線程處理的條件(簡單的例子:一個整數遞增)。

現在,爲了解決您的問題,線程1可以使用一個條件變量伴隨一個就緒布爾值來在其他線程準備好接收條件變量信號時發出信號,但是您最好先檢查原始條件變量是否可以按照此處所述使用。基於問題(還需要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(); 
} 

也看到my previous answer