1,考慮以下Reader/Writer情景:c++
有一個共享FIFO,寫線程往FIFO裏面寫數據,讀線程從FIFO裏面讀取數據。this
站在讀者的角度,若是FIFO爲空,讀者有兩種選擇:一種是輪詢FIFO,直到FIFO不空,讀取數據。這種輪詢的方式會佔滿CPU,浪費計算資源;另一種是讀者wait在某個等待隊列上,主動放棄CPU資源,等待寫者寫入FIFO後,再喚醒等待在這個隊列上的讀者。這就是wait/notify機制。線程
C++的wait/notify實現須要信號量mutex和條件變量condition_variable共同實現。c++11
2,C++中wait/notify實現示例:接口
std::mutex mMutex;隊列
std::condition_variable<std::mutex> mCondVar;資源
寫者線程(往mMsgQueue中寫入message):it
{
std::unique_lock<std::mutex> lock(mMutex);io
mMsgQueue.push_back(message);
mCondVar.notify_all();
}
變量
讀者線程(從mMsgQueue中讀取message):
{
std::unique_lock<std::mutex> lock(mMutex);
mCondVar.wait(lock, [this] {return !this->mMsgQueue.empty();});
msg = mMsgQueue.front();
mMsgQueue.pop_front();
mCondVar.notify_all();
}
其中,mMutex用來保護mMsgQueue共享資源互斥訪問。mCondVar.wait()用做條件等待,當條件不知足時(即,條件變量返回false),wait方法將當前線程掛起在mCondVar等待隊列上,unlock mMutex鎖,喚醒等待在mCondVar等待隊列上的其餘線程,從而使得其餘線程有機會運行。當條件知足時(即,條件變量返回true),wait方法不去休眠,在mMutex的保護下繼續運行。mCondVar.notify_all()方法用於喚醒全部等待在mCondVar等待隊列上的線程,若是時寫線程運行完畢,則須要喚醒讀線程去讀取;若是是讀線程讀取完畢,則須要喚醒寫線程寫入。
固然,c++11還提供了 notify_one()接口,用於喚醒在等待隊列上的某一個線程,提供這個方法的目的是爲了不在某些狀況下引發的驚羣效應。