C++ GCC 中的函数静态变量是线程安全的吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1270927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:24:19  来源:igfitidea点击:

Are function static variables thread-safe in GCC?

c++gccstaticinitializationthread-safety

提问by CsTamas

In the example code

在示例代码中

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

compiled with GCCis it guaranteed that bwill be created and initialized in a thread-safe manner ?

使用GCC 编译是否可以保证b以线程安全的方式创建和初始化?

In gcc's man page, found the -fno-threadsafe-staticscommand line option:

在 gcc 的手册页中,找到了-fno-threadsafe-statics命令行选项:

Do not emit the extra code to use the routines specified in the C++ ABI for thread-safe initialization of local statics. You can use this option to reduce code size slightly in code that doesn't need to be thread-safe.

不要发出额外的代码来使用 C++ ABI 中指定的例程进行局部静态的线程安全初始化。您可以使用此选项在不需要线程安全的代码中稍微减少代码大小。

  1. Does it mean, that local statics are thread-safe by default with GCC ? So no reason to put explicit guarding e.g. with pthread_mutex_lock/unlock?

  2. How to write portable code - how to check if compiler will add its guards ? Or is it better to turn off this feature of GCC ?

  1. 这是否意味着,默认情况下,本地静态在 GCC 中是线程安全的?所以没有理由把明确的守卫,例如pthread_mutex_lock/unlock

  2. 如何编写可移植代码 - 如何检查编译器是否会添加其防护?还是关闭 GCC 的这个功能更好?

采纳答案by CB Bailey

  1. No, it means that the initializationof local statics is thread-safe.

  2. You definitely want to leave this feature enabled. Thread-safe initialization of local statics is very important. If you need generally thread-safe access to local statics then you will need to add the appropriate guards yourself.

  1. 不,这意味着local s的初始化static是线程安全的。

  2. 您肯定希望启用此功能。localstatic的线程安全初始化非常重要。如果您需要对 local 进行一般线程安全的访问,static那么您需要自己添加适当的保护。

回答by shojtsy

We had serious issues with the locking code generated by GCC 3.4 to protect local static initialization. That version used a global shared mutexto protect all and any static initialization which lead to a deadlock in our code. We had a local static variable initialized from a result of a function, which started another thread, which created a local static variable. Pseudocode:

我们在 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();
  ...
}

The only solution was to disable this feature of gcc. If you need your code to be portable , which we did, you can not anyway depend on a feature added in a specific gcc version for thread safety. Supposedly C++0x adds thread-safe local statics, until then this is non-standard magic which makes your code non-portable, so I am advising against it. If you decide to use it, I suggest you validate that your gcc version does not use a single global mutex for this purpose by writing a sample application. (The difficulty of thread-safety is apparent from the fact that even gcc can not get it right)

唯一的解决方案是禁用 gcc 的此功能。如果你需要你的代码是可移植的,我们就是这样做的,你无论如何都不能依赖在特定 gcc 版本中添加的功能来保证线程安全。据说 C++0x 添加了线程安全的本地静态,在此之前这是非标准的魔法,它使您的代码不可移植,所以我建议不要这样做。如果您决定使用它,我建议您通过编写示例应用程序来验证您的 gcc 版本没有为此目的使用单个全局互斥锁。(线程安全的难点,从连gcc都搞不定的事实可见一斑)

回答by sbi

This is not really answering your questions straight away (Charles already did that), but I think it's time to post a link to this articleagain. It throws light on the initialization of globals and should be read and understood by everyone attempting to use staticvariables in a multi-threaded environment.

这并没有真正立即回答您的问题(查尔斯已经这样做了),但我认为是时候再次发布指向本文的链接了。它阐明了全局变量的初始化,每个试图static在多线程环境中使用变量的人都应该阅读和理解。

回答by Stephen C

I think that the key phrase is

我认为关键短语是

... thread-safe initializationof local statics.

...局部静态的线程安全初始化

I read this as meaning that it is only initialization of statics that would be done in a thread-safe way. General use of statics would not be thread-safe.

我认为这意味着它只是以线程安全的方式完成的静态初始化。静态的一般使用不是线程安全的。