c++11 condition_variable的問題?
#include &
#include &
#include &
#include &
using namespace std;int main()
{
condition_variable cv;
mutex a;
thread t1([]
{cout &<&< "notify one" &<&< endl; cv.notify_one(); }); thread t2([] { //this_thread::sleep_for(chrono::milliseconds(100)); unique_lock&
求大神賜教啊g(a);
cv.wait(g);
cout &<&< "received notification" &<&< endl; }); t1.join(); t2.join(); return 0; }以上的代碼創建兩個線程,t2等待t1 notify,可是如果t1在t2 wait 之前發送notify,例如讓t2 sleep一段時間,好像t2就收不到nofity,一直出不來了?
怎麼解決這個問題?
以我的經驗。。。。。
我不能理解為什麼這個cv是用局部變數。。。回到正題,遇到這種問題本來就是無解的,因為notify本來就是不管有沒有cv接收到就返回的。所以遇到這種情況需要先判斷另一個線程是不是在wait。可以再一個cv,當t2線程wait前再notify一下t1。然後兩個線程要共用一個mutex,或者用帶參數的wait,注意裡面最好用atomic你是從哪兒學的 condition variable 的用法?
記狀態最好用信號量,不過C++11沒有原生支持,可以用mutex和cv自己實現一個。
class semaphore
{
public:
semaphore() : count(0) {}
void notify_one()
{
unique_lock&
++count;
cv.notify_one();
}
void wait()
{
unique_lock&
while (count == 0)
cv.wait(lock);
--count;
}
private:
mutex m;
condition_variable cv;
int count;
};
int main()
{
semaphore s;
thread t1([]
{
// this_thread::sleep_for(chrono::seconds(1));
cout &<&< "notify one" &<&< endl;
s.notify_one();
});
thread t2([]
{
// this_thread::sleep_for(chrono::seconds(1));
s.wait();
cout &<&< "received notification" &<&< endl;
});
t1.join();
t2.join();
return 0;
}
問題: 線程1notify時,線程2可能沒開始等。。
建議先看看文檔
http://en.cppreference.com/w/cpp/thread/condition_variable
你這個要work的話,wait得加第二個參數作為predicate,去看一下C++的cv到底怎麼用的。
我也是新手,最近在看cv,有幾點:1. thread1在notify時需要先acquire mutex,通常用一個boost::scoped_lock或者std::lock_guard2. thread2的mutex在wait結束後會自動lock,這裡可能需要手動釋放或者也用lock_guard,這點請懂的同學再指點下
3. 整個程序要想work需要先wait在notify,這兩個thread實際執行時的順序現在沒法保證吧
看到碩爺答題了,補充一下。
/*正確用法如下:即使t1在t2 wait 之前發送notify,(如讓t2 sleep一段時間),t2依然可以收到nofity:(想想condition_variable的正確用法是什麼,錯誤用法又錯在哪裡?)*/
#include &
#include &
#include &
#include &
using namespace std;
//正確用法:
condition_variable cv;
mutex a;
int i=0;
int main()
{
thread t1([] /*ubuntu16.04 ,clang++3.8.0 運行結果:
{
i++;
//usleep(1000);
cout &<&< "notify one" &<&< endl;
cv.notify_one();
});
thread t2([]
{
this_thread::sleep_for(chrono::seconds(3));//等待3s
unique_lock&
//sleep(3);//linux:3s
cv.wait(g,[]{return i&>0; });
cout &<&< "received notification" &<&< endl;
});
t1.join();
t2.join();
return 0;
}
notify one
received notification
*/
cv的使用要和一個判斷條件綁定,在把判斷條件更新為true後notify,wait收到notify後要判斷條件是否成立 如成立結束等待,否則繼續等待
推薦閱讀:
※JSON「最後不能加逗號」是不是錯誤設計?
※我知道英語很重要,也很想學英語,但總是很懶,不想背單詞怎麼辦?
※為什麼大多數編程語言只有異或運算符而沒有同或運算符?
※為什麼棧沒有讀取並彈出的函數?
※Qt 如何打包一個軟體?