class SelfTesting
{
private:
char * pChar;
SelfTesting()
{
pChar = new char[1024 * 1024 * 1024];
}
public:
static SelfTesting * pSelf;
static SelfTesting& GetInst()
{
if (!pSelf)
{
boost::lock_guard<boost::mutex> lock(g_boost_mutex);
if (!pSelf)
{
pSelf = new SelfTesting;
}
}
return *pSelf;
}
};
一般来说,我知道问题是由以下原因引起的:
1. allocate memory for `SelfTesting`
2. store the pointer to the allocated memory in `pChar`
3. initialize `SelfTesting`
答案 0 :(得分:3)
正如所写,这种模式在任何版本的C ++中都不安全。在C ++ 11术语中,您在外部读取pSelf
和写入pSelf
之间存在数据争用。
一般来说,在C ++之前的版本11中,没有保证多线程代码的安全性。关于C ++ 11最重要的一点是它在C ++执行的抽象模型中引入了可能首先存在多个执行线程的想法。在此之前,对于多线程执行绝对没有任何保证,因为这个概念并不存在。就标准而言,任何有多个线程的情况都是未定义的,因为它没有定义线程是什么。
这基本上意味着您在C ++ 98中编写的任何多线程代码完全取决于您使用的特定实现。主流编译器有一些你可以依赖的东西,尽管在C ++ 11的开发中,在有多个线程时,在各种编译器中发现了几个行为(特别是优化),这些行为实际上并不安全。
但这一切都无关紧要,因为你所编写的代码从来没有保证在我所知道的任何编译器中都是安全的。使用Visual C ++,您可以通过使pSelf
volatile
(VC ++处理的volatile
变量类似于原子)使其安全,但这在GCC中不起作用。在GCC中,您必须使用原子内在函数或Boost.Atomic库。