簡體   English   中英

函數靜態變量是否在GCC中是線程安全的?

[英]Are function static variables thread-safe in GCC?

在示例代碼中

void foo()
{
  static Bar b;
  ...
}

使用GCC編譯是否可以保證以線程安全的方式創建和初始化b

在gcc的手冊頁中,找到了-fno-threadsafe-statics命令行選項:

不要發出額外的代碼來使用C ++ ABI中指定的例程來進行本地靜態的線程安全初始化。 您可以使用此選項在不需要線程安全的代碼中略微減小代碼大小。

  1. 這是否意味着,默認情況下,GCC的本地靜態是線程安全的? 所以沒有理由用pthread_mutex_lock/unlock來明確保護?

  2. 如何編寫可移植代碼 - 如何檢查編譯器是否會添加其防護? 或者關閉GCC的這個功能是否更好?

  1. 不,這意味着本地static s的初始化是線程安全的。

  2. 您肯定希望啟用此功能。 本地static s的線程安全初始化非常重要。 如果您通常需要線程安全訪問本地static s,那么您需要自己添加適當的防護。

我們對GCC 3.4生成的鎖定代碼存在嚴重問題,以保護本地靜態初始化。 該版本使用全局共享互斥鎖來保護所有和任何導致代碼死鎖的靜態初始化。 我們有一個從函數結果初始化的局部靜態變量,它啟動了另一個線程,它創建了一個本地靜態變量。 偽代碼:

voif f()
{
  static int someValue = complexFunction();
  ...
}
int complexFunction()
{
  start_thread( threadFunc() );
  wait_for_some_input_from_new_thread();
  return input_from_new_thread;
}
void threadFunc()
{
  static SomeClass s();
  ...
}

唯一的解決方案是禁用gcc的這個功能。 如果你需要你的代碼是可移植的,那么你無論如何都不能依賴於特定gcc版本中添加的功能來保證線程安全。 據說C ++ 0x添加了線程安全的本地靜態,直到那時這是非標准魔法,這使得你的代碼不可移植,所以我建議反對它。 如果您決定使用它,我建議您通過編寫示例應用程序來驗證您的gcc版本不會為此目的使用單個全局互斥鎖。 (線程安全的難度從即使是gcc也無法正確的事實中顯而易見)

這並不是馬上回答你的問題( Charles已經這樣做了 ),但我認為是時候再次發布這篇文章的鏈接了。 它揭示了全局變量的初始化,並且每個嘗試在多線程環境中使用static變量的人都應該閱讀並理解它。

我認為關鍵詞是

...本地靜態的線程安全初始化

我讀到這意味着它只是以線程安全的方式完成靜態的初始化。 靜態的一般使用不是線程安全的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM