函数静态变量析构函数和线程
Posted
技术标签:
【中文标题】函数静态变量析构函数和线程【英文标题】:function static variable destructor and thread 【发布时间】:2013-06-21 16:09:54 【问题描述】:我有一个简单的程序。
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
的阻塞操作。
这个程序成功打印“end”并退出,这里没有问题。 (有一个错误,当thread
启动时b
为假,导致它立即退出,但这与此处无关)
但是如果我将所有这些都包装在一个类中
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();
现在程序打印“end”然后卡在o
的析构函数thread.join()
处。
我已经用clang测试了这个,没有问题。这似乎只发生在 VC11 中。这是为什么?
【问题讨论】:
我看不出代码有什么问题。一种可能性是您在 VC11 处理静态初始化程序中的线程生成时发现了一个错误,这似乎是一个可能存在错误的边缘情况。另一个是您在 ConcurrentQueue 中有一个错误,您没有显示。 静态对象什么时候会被删除? dauphic:在我看来是正确的:设置原子标志,推送一条记录以确保在设置标志后至少唤醒一次,然后等待不可避免的线程退出。 是的。我误读了代码,并认为由于某种原因连接发生在main
。看起来不错。
@AndyRoss 我用 TBB 的 tbb::concurrent_bounded_queue
替换了我的 ConcurrentQueue
,但问题仍然存在。
【参考方案1】:
最近有一个帖子遇到同样的问题,但我找不到了。
基本上,当您有一个静态生命周期对象试图在其析构函数中结束线程时,VS 的运行时库中会出现死锁。
【讨论】:
在析构函数工作之前加入......似乎是一个临时工作,直到他们修复它。谢谢以上是关于函数静态变量析构函数和线程的主要内容,如果未能解决你的问题,请参考以下文章