2012-06-26 56 views
1

聽說用簡單的類似的gcc的某個版本之後:gcc 4之後的C++中的線程安全單例?

static A* a = new A(); 
return a; 

是線程安全的單,一個將不需要的東西改編自說http://locklessinc.com/articles/singleton_pattern/了...

有誰有具體的參考資料或鏈接到我可以閱讀的地方?

+0

您實際上不需要使用operator new來創建單例。因此不需要關鍵部分。 – mfontanini

+1

@mfontanini:使用'new'以內存泄漏爲代價避免了破壞命令的失敗。在C++中實現單例沒有好的方法,但有很多不好的方法可供選擇。 –

+0

@MikeSeymour:我仍然會返回一個*引用* –

回答

3

標準草案(n3337.pdf),點4的第6.7節:

具有靜態存儲的持續時間(3.7.1)或線程存儲 持續時間的所有塊範圍變量的零初始化(8.5)( 3.7.2)在進行任何其他初始化之前執行。在第一次輸入塊之前,執行具有靜態存儲持續時間的塊範圍實體的常量初始化(3.6.2)(如果適用)。 允許實現在靜態或 線程存儲持續時間內執行其他塊範圍變量的早期初始化,允許實現在靜態初始化 命名空間範圍內具有靜態或線程存儲持續時間的變量(3.6.2 )。否則,這種變量是 第一次控制通過它的聲明初始化;這樣的變量在初始化完成時被認爲初始化。如果通過拋出異常退出初始化,則初始化 未完成,因此下次控制進入聲明時將再次嘗試初始化。 如果控制在變量初始化時同時輸入 聲明,則併發執行應等待 初始化完成 .88如果控制器初始化時遞歸地重新輸入聲明,則該行爲是未定義的。

+0

關於遞歸位,gcc通過在這種情況下拋出一個特定的異常來防範。 –

+0

這不是創建單身人士。 –

1

GCC遵循跨廠商Itanium C++ ABI。涵蓋的功能,本地靜態線程安全初始化的相關章節是2.8 Initialization guard variables3.3.2 One-time Construction API,它說:

不預期支持多線程可以簡單地檢查第一個字節(即字節具有最低的實現地址),當且僅當其值爲零時初始化,然後將其設置爲非零值。

然而,打算支持自動線程安全的,一次性初始化(相對於需要線程安全的明確的用戶控制),可選用下列API函數的實現: ...

該API的早期GCC實現中存在一些錯誤,我認爲它們都是固定的,並且它可以從GCC 4.3版本正確工作(可能更早,我不記得,現在也找不到參考文件。)

但是,Singleton is a bad,不好的模式,請不要使用它!