2016-08-11 54 views
0

這裏是一個C++參考網站當condition_variable :: wait()被調用時,解鎖unique_lock會發生什麼?

#include <chrono> 
#include <condition_variable> 
#include <iostream> 
#include <mutex> 
#include <thread> 

std::mutex mtx; 
std::condition_variable cv; 
bool ready = false; 

void print_id(int id) { 
    std::unique_lock<std::mutex> lck(mtx); 
    while (!ready) { 
     lck.unlock(); // by curiosity I unlock the lck 
     cv.wait(lck); 
    } 
    std::cout << "thread " << id << '\n'; 
} 

void go() { 
    std::unique_lock<std::mutex> lck(mtx); 
    ready = true; 
    lck.unlock(); 
    cv.notify_all(); 
} 

int main() { 
    std::thread threads[10]; 
    for (int i = 0; i < 10; ++i) 
     threads[i] = std::thread(print_id, i); 
    go(); 
    for (auto &th : threads) 
     th.join(); 

    return 0; 
} 

上的示例代碼。如果我不調用wait(前解鎖unique_lock),一切工作正常。像:

thread 9 
thread 1 
thread 2 
thread 3 
thread 4 
thread 5 
thread 6 
thread 7 
thread 8 
thread 0 

我已經告訴

在阻塞線程的時刻,函數(wait())自動調用lck.unlock(),允許其他鎖定線程繼續。

所以我想如果我解開unique_lock前等待什麼()是called.After我這樣做,程序行爲古怪,只有一個或兩個線程完成自己的工作(打印「線程X」的消息),其他線程似乎永遠被阻塞(由unique_lock?)。

這些unique_locks發生了什麼?或者它只是在wait()之前調用unlock()的另一個未定義的C++行爲?

謝謝!

+0

「所以我想知道如果我在調用wait()之前解鎖unique_lock。」爲什麼? – Slava

+1

「我這樣做之後,程序表現得很奇怪」 - 幾乎定義了未定義行爲,就在那裏...... –

回答

3

如在std::condition_variable::wait()

調用此函數文檔指出,如果lock.mutex()不被當前線程鎖定是不確定的行爲。

+0

非常感謝。我試圖出於好奇,而沒有仔細閱讀參考資料:(但爲什麼標準不允許這樣做?是否表明這種行爲對數據是不安全的? – XaL

+0

@XaL條件變量的整體目的是允許一個線程解鎖一個互斥體並進入睡眠狀態**原子化**並執行相反的操作,所以你的問題類似於:「爲什麼啤酒開瓶器不工作沒有啤酒? – Slava

相關問題