2017-05-13 30 views
1

我們知道條件變量受到虛假喚醒的影響。假設我們有一個1-producer-1-consumer隊列與一個互斥鎖和條件變量同步。消費者線程被虛假喚醒。 問題是 - 消費者線程是否會錯過生產者的通知信號? 我知道這是非常不可能的..但是仍然有可能失去排隊中的最後一個元素與這種實現?如果虛假喚醒,消費者線程是否會收到condition_variable通知信號

+0

_「消費者線程是否會錯過來自生產者的通知信號?」_爲什麼要這樣?這就是爲什麼有一個與cv一起使用的互斥體。你可以向你展示一個[MCVE]的內容嗎? –

+0

afaik條件變量的整點是處理虛假喚醒的情況 – user463035818

回答

2

如果調用wait()代碼不寫吧,它可能確實,錯過了一個醒。但那會有點不正當。通常的習慣用法是:

lock the mutex 
while the condition is not satisfied 
    wait on the condition variable 

信令螺紋信令之前應該鎖定互斥:

lock the mutex 
signal the condition variable 

等待條件變量解鎖用於等待的持續時間互斥。但是等待調用返回時,互斥鎖將被鎖定。所以在一個虛假的喚醒中,等待線程將持有該互斥體直到它恢復等待。當等待的線程持有互斥量時,信號線程不能發信號通知條件變量。當等待的線程實際等待時,互斥體被解鎖,並且信號線程可以繼續併發出信號;等待線程將獲得信號,一旦信號線程釋放互斥量,等待線程將恢復執行。

所以,不,正確的代碼不會錯過任何信號。但是,如果等待線程在檢查其狀態的過程中釋放互斥鎖並重新獲取它,則信號可能在等待線程調用等待之前發生,並且信號將丟失。不要這樣做。 < g>

+0

「當等待的線程持有互斥鎖時,信號線程不能發信號通知條件變量。」 - 那就是我錯過的。謝謝! – Sergei

1

虛假喚醒意味着它可能會虛假地喚醒,然後不得不繼續等待。

它完全沒有提到錯過事件的可能性,因爲如果這是真的,那將是沒有用的。

此鏈接提供簡歷的詳細解釋和wait方法:

https://www.codeproject.com/Articles/598695/Cplusplus-threads-locks-and-condition-variables

// print a starting message 
    { 
     std::unique_lock<std::mutex> locker(g_lockprint); 
     std::cout << "[logger]\trunning..." << std::endl; 
    } 

    // loop until end is signaled 
    while(!g_done) 
    { 
     std::unique_lock<std::mutex> locker(g_lockqueue); 

     g_queuecheck.wait(locker, [&](){return !g_codes.empty();}); 

     // if there are error codes in the queue process them 
     while(!g_codes.empty()) 
     { 
      std::unique_lock<std::mutex> locker(g_lockprint); 
      std::cout << "[logger]\tprocessing error: " << g_codes.front() << std::endl; 
      g_codes.pop(); 
     } 
    } 
相關問題