我有一个简单的程序。
int main()
{
std::atomic<bool> b = true;
ConcurrentQueue<std::string> queue;
std::thread thread( [&]{
while ( b ) {
auto str = queue.wait_and_pop();
std::cout << *str;
}
});
b = false;
queue.push( "end" );
thread.join();
}
ConcurrentQueue<T>
是我自己的线程安全队列实现,wait_and_pop
是一个使用std::condition_variable
的阻塞操作。
这个程序成功打印“结束”并退出,这里没问题。 (当b
启动时,thread
有一个错误,导致它立即退出,但这与此无关)
但如果我将所有这些包装在一个类
中class object {
public:
object() {
b = true;
thread = std::thread( [this]{
while ( b ) {
auto str = queue.wait_and_pop();
std::cout << *str;
}
});
}
~object() {
b = false;
queue.push( "end" );
thread.join();
}
private:
std::atomic<bool> b;
std::thread thread;
ConcurrentQueue<std::string> queue;
};
并有一个函数静态变量,如
object & func() {
static object o;
return o;
}
和主要
int main() {
object & o = func();
}
现在程序打印“结束”,然后停留在行o
的{{1}}的析构函数中。
我用clang测试了这个并没有问题。这似乎只发生在VC11中。这是为什么?
答案 0 :(得分:5)
最近有一个线程有同样的问题,但我再也找不到了。
基本上,当你有一个静态生命周期对象试图在它的析构函数中结束一个线程时,VS的运行时库就会出现死锁。