2012-09-22 38 views
0

(假设VC++ 2010:(1)可以使用/易失性:毫秒,(2)无标准::原子又,(3)没有线程安全静态变量初始化,( 4)无标准:: call_once的)如何使用双重检查锁初始化一个shared_ptr

如果我有一个普通的C指针,我可以IMPL以下双重检查锁定模式,以避免锁定的成本每次:

static volatile void * ptr = nullptr; 

//... 
if (ptr == nullptr) 
{ 
    // Acquire Lock 
    if (ptr == nullptr) 
    { 
     // some code 
     // ptr = ...; // init ptr 
    } 
    // Release Lock 
} 
// .... 

由于VC++ 2005,该volatile会确保上面的代码是正确的。假设我确定代码不可移植。

现在假设我需要一个std :: shared_ptr的替换普通的指针或升压:: shared_ptr的,我怎么会做同样的事情?如何使该shared_ptr易变?我需要另一个挥发性旗帜吗?

+2

没有,没有。双重检查锁定是不好的。 – Puppy

+3

是什么让你相信'volatile'使得代码正确? –

+0

如果您将'static volatile void * ptr = nullptr;'更改为'std :: atomic ptr = nullptr;'双重检查的锁定将起作用。这假定C++ 11。 –

回答

3

由于VC++ 2005,挥发确保上面的代码是正确的。

不,不。 volatile与线程或原子无关。

您目前的代码是不正确的,并且不会由任何C++标准保证产生合理的行为。

因为你假装锁定代码不做工一般,它肯定不会对shared_ptr或其他智能指针工作。如果您想要更便宜的锁定,请查看无锁定编码模式。

+1

在_Visual C++ _中,OP专门提到了'易挥发“保证完整的内存围栏。如果这个问题是关于标准C++的,那么你完全正确,但是我不觉得这就是问题所在。 – ildjarn

+0

是的。我应该清楚这是关于VC++特定的代码(使用/ volatile:ms)。因此上面的代码是正确的。 –

4

用C++ 11,存在用于shared_ptr原子存取器函数。编写使用shared_ptr一个双重检查锁,使用这些访问器:

static std::shared_ptr<MyType> ptr; 
if (std::atomic_load(ptr) == 0) { 
    // lock the lock 
    if (std::atomic_load(ptr) == 0) { 
     std::shared_ptr<MyType> local_ptr(new MyType); 
     std::atomic_store(ptr, local_ptr); 
    } 
    // unlock the lock 
} 
return ptr; 
+0

std :: atomic会很理想。不幸的是,我需要使用VS2010。 –

1

在C++ 2011它甚至不是necesary使用任何显式同步。根据6.7 [stmt.dcl]段落4的初始化是由系统同步:

如果控制进入声明同时而可变正在初始化,并发执行应等待初始化的完成。

这似乎意味着std::shared_ptr<T>可以这样initialzed:

{ 
    static std::shared_ptr<MyType> ptr(new MyType(/*...*/)); 
    // ... 
} 
+0

谢谢。但是,AFAIK,这个功能甚至不在VC2012中(如果我错了,请纠正我)。另外,(1)它是否使用延迟初始化? (2)如果我在调用ctor之前需要在“//一些代码”部分中使用一些代价高昂的逻辑,它仍然不是理想的。 –

+0

这是懒惰的初始化,无论如何你需要在某个点进行昂贵的初始化。如果初始化不适合构造函数,则可以调用返回'std :: shared_ptr '的函数。这些实现会应用类似'std :: call_once()'的东西来确保线程在初始化过程中被正确阻塞,并且之后受到的阻碍最小。我不知道是否有编译器实现了这个功能。我仍然认为指出它是如何正确完成是非常有用的。 –

+0

@LostInTranslation:你是对的:VC++ 2012 - 根据[本博文](http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx)N2660是未实现。 – ildjarn

相关问题