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& lock(m);
++count;
cv.notify_one();
}

void wait()
{
unique_lock& lock(m);
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_guard

2. 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 &
#include &
using namespace std;
//正確用法:
condition_variable cv;
mutex a;
int i=0;

int main()
{

thread t1([]
{
i++;
//usleep(1000);
cout &<&< "notify one" &<&< endl; cv.notify_one(); }); thread t2([] { this_thread::sleep_for(chrono::seconds(3));//等待3s unique_lock& g(a);
//sleep(3);//linux:3s
cv.wait(g,[]{return i&>0; });
cout &<&< "received notification" &<&< endl; }); t1.join(); t2.join(); return 0; }

/*ubuntu16.04 ,clang++3.8.0 運行結果:

notify one  

received notification

*/


cv的使用要和一個判斷條件綁定,在把判斷條件更新為true後notify,wait收到notify後要判斷條件是否成立 如成立結束等待,否則繼續等待


推薦閱讀:

JSON「最後不能加逗號」是不是錯誤設計?
我知道英語很重要,也很想學英語,但總是很懶,不想背單詞怎麼辦?
為什麼大多數編程語言只有異或運算符而沒有同或運算符?
為什麼棧沒有讀取並彈出的函數?
Qt 如何打包一個軟體?

TAG:編程 | C | 多線程 | C11 | vczh知乎用戶 |