2015-05-13 27 views
4

在我無休止的追求,以瞭解std::contion_variable的I碰到的下面。在this page它說以下內容:爲什麼既是性病的通知,並等待功能:: condition_variable需要一個鎖定的互斥

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

它說,這之後:

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

現在據我瞭解,這兩種功能將暫停在std::unqique_lock線。直到獲得獨特的鎖定。也就是說,沒有其他線程有鎖。

所以說print_id功能首先執行。這個獨特的鎖將會被使用,並且這個功能會在等待線上停下來。

如果隨後執行go功能(在單獨的線程),代碼有將停止在唯一的鎖線。由於該互斥鎖已被print_id函數鎖定。

顯然,如果代碼是一樣,這是行不通的。但我真的沒有看到我不在這裏。所以請賜教。

+0

我不認爲print_id應該使用相同的鎖。鎖在那裏,所以只有一個線程可以運行print_id,並且只有一個線程運行go()。 –

+1

嗯我檢查http://en.cppreference.com/w/cpp/thread/condition_variable和生產者和消費者都使用相同的鎖。奇。 –

+0

@Angew你的意思是「保護條件變量本身」?條件變量不是固有的線程安全嗎? – laurisvr

回答

9

你缺少的是wait解鎖互斥鎖,然後等待cv上的信號。

它在返回之前再次鎖定互斥鎖。

你可以通過點擊wait在頁面上已經發現了這一點,你找到了例子:

在阻塞線程的瞬間,該功能會自動調用lck.unlock(),允許其他鎖定線程繼續。

一旦通知(明確,其它線程),該函數疏導,並調用lck.lock(),留在同一國家LCK當函數被調用。

+0

啊謝謝你,清除了事情:)。我的誤解是因爲我認爲調用notify的函數可能無法通過互斥鎖定。但是,當然,如果這個互斥體已經被等待解鎖了,它當然可以。 – laurisvr

3

有一個點,你已經錯過了—調用wait()解鎖互斥。原子線程(釋放互斥+進入睡眠)。然後,當被信號喚醒時,它試圖重新獲得互斥(可能阻塞);一旦獲得它,它就可以繼續。

請注意,這是沒有必要有互斥鎖調用notify_*,只爲wait*

+1

事實上,它可能是_pessimization_在發信號通知條件變量時持有鎖。當您通知它時,調度程序可能會喚醒等待的線程,然後該線程無法取得鎖定,因爲通知線程仍然有可能導致線程立即生效!這會導致不必要的顛簸。顯然,調度程序可以與CV代碼進行綁定,並且不會喚醒等待的線程,除非它也可以立即獲得互斥鎖。注意:這與pthreads_CV相反,它需要鎖定在通知上的互斥體。 –

0

要回答(如提出的問題,這似乎是必要的有關要求,你不應該在通知獲得鎖的性能方面的原因是不是正確性比性能更重要?):鎖定「等待」的必要性和始終鎖定「通知」的建議是爲了保護用戶免受自己和他的程序的數據和邏輯競爭。如果沒有鎖定「發送」,您發佈的程序將立即進行「準備好」數據競賽。然而,即使準備進行自身同步(例如原子),你將有一個未接通知邏輯的比賽,因爲沒有在「走出去」鎖就可以了通知發生只是在檢查「後準備「和之前實際等待,等待的線程可能會無限期地被阻止。原子變量本身的同步不足以防止這種情況發生。這就是爲什麼helgrind會在沒有鎖的情況下通知完成時發出警告。有一些附帶的情況下,通知周圍確實不需要互斥鎖。在所有這些情況下,都需要事先進行雙向同步,以便生成線程可以確定其他線程已經在等待。國際海事組織這些案件僅限於專家。實際上,我曾經見過一位專家,談論多線程,弄錯了 - 他認爲一個原子計數器就足夠了。也就是說,圍繞等待的鎖始終需要正確性(或者至少等待原子的操作),這就是爲什麼標準庫強制執行並在進入等待時原子解鎖互斥鎖的原因。

與Windows事件不同,POSIX條件變量不是「防白癡」,因爲它們是無狀態的(除了意識到等待線程)之外。對通知使用鎖定的建議是爲了保護您免受最壞和最常見的折磨。當然,如果你喜歡,你可以使用互斥+條件var + bool變量來構建一個類似Windows的狀態事件。

+1

鎖通常不是必需的,但它對條件的更改是必需的(實際上使用atomic將是一個錯誤)。 – Cubbi

相關問題