2014-07-06 46 views
3

我在Ubuntu 13.04桌面上運行這個非常簡單的程序,但是如果我註釋掉sleep_for行,它會在從main打印cout之後掛起。誰能解釋爲什麼?據我所知,main是一個線程,t是另一個線程,在這種情況下,互斥量管理共享cout對象的同步。std :: thread C++ 11無法解釋爲什麼

#include <thread> 
#include <iostream> 
#include <mutex> 

using namespace std; 
std::mutex mu; 

void show() 
{ 
std::lock_guard<mutex> locker(mu); 
cout<<"this is from inside the thread"<<endl; 
} 

int main() 
{ 
std::thread t(show); 
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 
std::lock_guard<mutex> locker(mu); 
cout<<"This is from inside the main"<<endl; 
t.join(); 
return 0; 
} 
+1

這是一個共同的代碼質量要求的原因,任何析構函數具有副作用的對象都應在範圍的開始處創建,除非有充分的理由不這樣做。 –

回答

7

如果更改爲main功能如下,代碼將如預期:

int main() 
{ 
    std::thread t(show); 
    { 
     std::lock_guard<mutex> locker(mu); 
     cout << "This is from inside the main" << endl; 
    } // automatically release lock 
    t.join(); 
} 

在代碼中,有一個不幸的競爭條件。如果線程t先獲得鎖定,則一切正常。但是,如果主線程首先獲得鎖定,它將保持鎖定,直到功能結束。這意味着,線程t沒有機會獲得鎖定,無​​法完成,主線程將阻止t.join()

2

這只是一個典型的死鎖:主線程獲取鎖,然後阻塞加入另一個線程,但另一個線程只能加入,如果設法獲得鎖。

相關問題