【发布时间】:2013-06-10 04:45:44
【问题描述】:
我已经在 C++ 中实现了一个单例(静态版本)。我知道关于这种模式和潜在线程安全问题的所有争议,但我很好奇为什么这个确切的实现不会停止。程序从不退出,最后一直处于死锁状态。
singleton.h:
#pragma once
#include <thread>
#include <atomic>
class Singleton
{
public:
static Singleton& getInstance();
private:
std::thread mThread;
std::atomic_bool mRun;
Singleton();
~Singleton();
void threadFoo();
};
单例.cpp
#include "singleton.h"
Singleton& Singleton::getInstance()
{
static Singleton instance;
return instance;
}
Singleton::Singleton()
{
mRun.store(true);
mThread = std::thread(&Singleton::threadFoo, this);
}
Singleton::~Singleton()
{
mRun.store(false);
if(mThread.joinable())
mThread.join();
}
void Singleton::threadFoo()
{
while(mRun)
{
}
}
main.cpp
#include "singleton.h"
int main()
{
Singleton::getInstance();
return 0;
}
我已经知道的:
- 线程终止
- 主线程卡在join中
- 它与静态有关,如果我公开构造函数并在 main() 中创建 Singleton 实例,它将正确终止。
使用 Visual Studio 2012。感谢您的建议。
【问题讨论】:
-
混合全局关闭和运行线程充其量是棘手的。目前我找不到任何标准参考,但我怀疑您正在尝试做的事情(让线程比 main 的结尾更有效)实际上是未定义的行为。
-
可能是因为静态实例比
main()寿命长。 -
这个程序在使用 gcc (
g++-4.8 test.cpp -O2 -pthread -std=c++0x) 编译时可以正常启动和结束。我不知道这对任何人是否有用 -
@Xcessity:承认你知道它,你只是想对 MS 错误进行攻击......呃我的意思是功能。 :)
-
静态变量在 main() 退出后被销毁。很可能有某种隐藏的内部线程列表 - 在其他地方,可能也是静态的,一旦 main() 完成,它也会被清理。在您的情况下,这很可能发生在您的 Singleton 被破坏并破坏线程行为之前。请注意,我实际上并没有对此进行测试,这只是我能想到的最有可能的情况。另外,假设你有专业版的 VS 和 crt 源代码,你应该可以跳出 main(),看看调试器会发生什么。
标签: c++ multithreading c++11 static singleton