2012-09-22 39 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

相關問題