C++中多线程与Singleton的那些事儿

发表于:2015-3-11 10:08

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:origins    来源:51Testing软件测试网采编

  local static
  上面一种写法只能在进入main函数后才能调用getInstance,那么有人说,我要在main函数之前调用怎么办?
  嗯,办法还是有的。这个时候我们就可以利用local static来实现,C++标准保证函数内的local static变量在函数调用之前被初始化构造完成,利用这一特性就可以达到目的:
template<typename T>
class Singleton
{
private:
Singleton();
~Singleton();
class Creater
{
public:
Creater()
: value_(new T())
{
}
~Creater()
{
delete value_;
value_ = NULL;
}
T& getValue()
{
return *value_;
}
T* value_;
};
public:
static T& getInstance()
{
static Creater creater;
return creater.getValue();
}
private:
class Dummy
{
public:
Dummy()
{
Singleton<T>::getInstance();
}
};
static Dummy dummy_;
};
template<typename T>
typename Singleton<T>::Dummy Singleton<T>::dummy_;
  这样就可以了。dummy_的作用是即使在main函数之前没有调用getInstance,它依然会作为最后一道屏障保证在进入main函数之前构造完成Singleton对象。这样就避免了在进入main函数后的多线程环境中初始化的各种问题了。
  但是此种方法只能在main函数执行之前的环境是单线程的环境下才能正确工作。
  实际上,上文所讲述了各种写法中,有一些不能在main函数之前调用。有一些可以在main函数之前调用,但是必须在进入main之前的环境是单线程的情况下才能正常工作。具体哪种写法是属于这两种情况就不一一分析了。总之,个人建议最好不要在进入main函数之前获取Singleton对象。因为上文中的各种方法都用到了staitc member,而C++标准只保证static member在进入main函数之前初始化,但是不同编译单元之间的static member的初始化顺序却是未定义的, 所以如果在main之前就调用getInstance的话,就有可能出现实现Singleton的static member还没有初始化就被使用的情况。
  如果万一要在main之前获取Singleton对象,并且进入main之前的环境是多线程环境,这种情形下,还能保证正常工作的写法只有C++ 11下的Meyers Singleton,或者如g++ 4.0及其后续版本这样的编译器提前支持内存模型情况下的C++ 03也是可以的。
44/4<1234
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号