8

我有一个简单的程序。

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”并退出,这里没有问题。(有一个错误bthread启动时是错误的,导致它立即退出,但这与这里无关)

但是,如果我将所有这些都包装在一个类中

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”然后停留在oat line的析构函数处thread.join()

我已经用clang测试了这个,没有问题。这似乎只发生在 VC11 中。这是为什么?

4

1 回答 1

5

最近有一个帖子有同样的问题,但我找不到了。

基本上,当你有一个静态生命周期对象试图在其析构函数中结束一个线程时,VS 的运行时库中就会出现死锁。

于 2013-06-21T16:20:41.360 回答