C ++ Singleton第一次创建实例是否安全?

时间:2014-10-22 15:20:39

标签: c++ multithreading

据我了解,如果在不同的线程中调用Singleton :: instance(),如果两个调用都引用了实际实例的第一个构造,则可能会出现问题。

因此,如果我将第一个Singleton :: instance()调用移动到程序的最开头,其中甚至没有创建其他线程,那么这现在是线程安全的吗?

当然,所有成员变量在使用时都受到互斥保护。

6 个答案:

答案 0 :(得分:4)

这可能让你的眼睛看到一个线程安全的Singleton,它是多么容易。 http://silviuardelean.ro/2012/06/05/few-singleton-approaches/

如前所述,如果您要求在任何线程开始之前创建它,它就不是很强大。

值得注意的是,如果你用C ++ 11编译,那么就像Brian所说的那样(静态存储+静态方法)可以保证线程安全。对于任何以前的版本,您将需要一个互斥锁,并将遇到我分享的链接中提到的警告。

答案 1 :(得分:3)

  

因此,如果我将第一个Singleton :: instance()调用移动到程序的最开头,其中甚至没有创建其他线程,那么这现在是线程安全的吗?

是的,但是这个元素不在Singleton的设计范围内,如果是这样的话可能会更强大。

您通常可以在static方法中使用static存储在文件范围或功能范围内分配它。验证您的编译器是否在其周围生成排除或在那里添加您自己的互斥锁。

答案 2 :(得分:1)

是的,执行初始实例化时,如果可以保证只有一个线程存在,则可以明显保护它免受其他线程的影响。

但是,它并没有感觉到非常强大。至少,在警告评论区域涂上灰泥。

答案 3 :(得分:0)

也许那时你不需要懒惰的单例实例初始化?

如果你真的想要它,那么你可以在构造时使用互斥锁保护单例实例。

答案 4 :(得分:0)

请记住不要放入标题 如果将实现放在标头中,则可以在使用它的每个编译单元中生成它。这意味着它不会是单一的。

也不要在静态库中编译它。如果代码被链接并合并到几个非静态库中,这也可能导致多个实例。

答案 5 :(得分:0)

如果还没有创建额外的线程,并且在创建这些线程之前进行了移动,我就不会通过使用您在任何新创建的多线程中创建的单例来查看可能存在问题的真实场景环境。

单线程模式进入多线程环境的主要线程安全问题是关于如何防止两个或更多单个"单例"不同线程创建的实例。我已将此场景描述为"多线程环境"第here节。