我正在Ubuntu 13.04桌面上运行这个非常简单的程序,但是如果我注释掉sleep_for行,它会在从main打印cout后挂起。有谁能解释为什么?据我所知,main是一个线程而t是另一个线程,在这种情况下,互斥锁管理共享cout对象的同步。
#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;
}
答案 0 :(得分: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
首先获得锁定,那么一切正常。但是如果主线程首先获得锁定,它将保持锁定直到main
函数结束。这意味着,线程t
没有机会获得锁定,无法完成,主线程将在t.join()
上阻止。
答案 1 :(得分:2)
这只是一个经典的死锁:主线程获得锁定然后在加入另一个线程时阻塞,但另一个线程只能在它设法获取锁定时加入。