2013-12-18 24 views
3

IMAGIN這樣的:通過C函數調用線程安全的靜態初始化?

void *ImCalledByThreads (/*...*/) 
{ 
    //some stuff 
    static typePlaceholder AmIThreadSafe = QuestionTag(); 
    //other stuff 
} 

這是初始化線程?

即使QuestionTag()是線程安全的,如果第一個線程運行該函數而另一個線程調用此行,會發生什麼情況。是否會檢測到函數只會執行一次?或者這對於多線程來說只是一個壞主意?

+2

這不是合法的C代碼。但是如果你在談論C++而不是C,那麼它肯定不是線程安全的。我不確定C++ 11是怎麼說的,但C++ 03和更早版本根本沒有提到線程。從我從各種編譯器看到的生成代碼中,他們不會在變量初始化的基礎上添加任何同步原語。 –

+1

@AdamRosenfield它在gcc(C++)中是線程安全的,C++ 11要求它是 – nos

+0

愚蠢的MSVC ....我說的是純粹的C但是我只是在Windows上測試了這個,沒有錯誤。但是我忘記了這對C++標準來說是不可靠的,因爲MSVC期望C代碼。不管怎麼說,還是要謝謝你。 – dhein

回答

3

這不是合法的C代碼,因爲C要求靜態變量的初始化器是編譯時常量。因此,在任何線程有機會啓動之前,可以在程序加載時進行初始化,因此在那裏沒有競爭條件。

從C99§6.7.8/ 4:

所有在對於具有靜態存儲期限爲常量表達式或字符串文字的對象的初始化表達式。

Visual Studio可能允許非常量作爲非標準擴展,但爲此,所有投注都將關閉。檢查它的文檔和/或它生成的彙編代碼,看它是否是線程安全的。

對於允許使用非常量初始值設定項的C++,請參閱問題Is initialization of local static function-object thread-safe?。簡短回答:是的,在C++ 11中,C++ 03及更早版本中沒有(沒有提及標準中的線程),儘管編譯器如果選擇它們仍然可以使其線程安全。

相關問題