如有錯誤請及時指正!
3.如何避免虛假喚醒
當我們使用linux幫助中有提到互斥量(mutex)
與條件變數(condition_variable)
進行多執行緒同步時有可能會產生虛假喚醒現象, 那麼究竟什麼是虛假喚醒
,它會在什麼情況下被觸發,什麼情況下無需考慮虛假喚醒,如何避免?
在多核處理器下,pthread_cond_signal可能會啟用多於乙個執行緒(阻塞在條件變數上的執行緒)。結果是,當乙個執行緒呼叫pthread_cond_signal()後,多個呼叫pthread_cond_wait()或pthread_cond_timedwait()的執行緒返回。這種效應成為」虛假喚醒」(spurious通俗點的解釋就是:wakeup)
你(消費執行緒)收到了其他執行緒(生產)傳來的喚醒訊號,但是你喚醒後發現別的消費執行緒處理的比你快,此時沒有資料被可以用於操作,這種情況的發生是預期之外的,稱之為虛假喚醒。以以下c++**舉例。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define producter_num 10
#define consumer_num 100
std:
:mutex mutexforproduct;
static queue<
unsigned
> queueforproduct;
unsigned uproducttotalnum =0;
condition_variable condval;
//生產線程
void
consumerfunction
(unsigned threadindex)
if(queueforproduct.
empty()
)unsigned productindex = queueforproduct.
front()
;printf
("consumer[%02u] buying product[%06u], remainsize= %lu\n"
, threadindex, productindex, queueforproduct.
size()
);queueforproduct.
pop();
}}//消費執行緒
void
producerfunction()
}int
main()
當生產者的數量(producter_num)大於1時,無論是使用notify_one,或者是notify_all都會發生虛假喚醒,當多個生產者使用notify_one時,多個執行緒被喚醒,有可能其中乙個處理的特別快,將所有的資料都處理完畢,那麼接下來被喚醒的執行緒都無資料可處理
所以得出以下結論:
只有在生產線程與消費執行緒都為多個的情況下才有可能發生虛假喚醒,只要有一方的數量為1,就不會發生!
將消費者執行緒修改如下
void
consumerfunction
(unsigned threadindex)
if(queueforproduct.
empty()
)unsigned productindex = queueforproduct.
front()
;printf
("consumer[%02u] buying product[%06u], remainsize= %lu\n"
, threadindex, productindex, queueforproduct.
size()
);queueforproduct.
pop();
}}
被喚醒後再次判斷,若無資料可處理,則應繼續休眠。 條件變數之虛假喚醒
接下來,給出 pthread cond wait 和 pthread cond signal 的偽 參考man pthread cond signal 語句後面的編號代表時間上的執行順序。pthread cond wait mutex,cond else pthread mutex lock mut...
深入理解條件變數 虛假喚醒
深入條件變數 pthread cond wait 和pthread cond signal 的偽實現 pthread cond wait mutex,cond 競爭失敗,那麼就不加入等待佇列了,相當於直接 喚醒 else pthread mutex unlock cond mutex 重新鎖住傳入的...
條件變數 虛假喚醒 放到while迴圈的原因
linux中幫助中提到 在多核處理器下,pthread cond signal可能會啟用多於乙個執行緒 阻塞在條件變數上的執行緒 結果是,當乙個執行緒呼叫pthread cond signal 後,多個呼叫pthread cond wait 或pthread cond timedwait 的執行緒返...