C ++ 11中的局部静态变量初始化是否是线程安全的?

时间:2011-11-12 02:34:55

标签: c++ thread-safety c++11

我知道这是一个经常被问到的问题,但由于有很多变种,我想重新陈述它,并希望有一个反映当前状态的答案。像

这样的东西
Logger& g_logger() {
    static Logger lg;
    return lg;
}

变量lg的构造函数是否保证只运行一次?

我从以前的答案中知道,在C ++ 03中,这不是;在C ++ 0x草案中,这是强制执行的。但我想更清楚地回答

  1. 在C ++ 11标准(非草稿)中,线程安全的初始化行为是否已完成?
  2. 如果以上是肯定的,那么在当前最新版本的热门编译器中,即gcc 4.7,vc 2011和clang 3.0,它们是否正确实施?

2 个答案:

答案 0 :(得分:170)

相关章节6.7:

  

这样的变量在控件第一次通过其声明时被初始化;这样的变量在初始化完成后被认为是初始化的。 [...]如果控件在初始化变量时同时进入声明,则并发执行应等待初始化完成。

然后有一个脚注:

  

实现不得在执行初始化程序时引入任何死锁。

是的,你很安全。

(这当然没有说明通过引用随后访问变量。)

答案 1 :(得分:13)

- fno-threadsafe-statics也值得一提。在gcc:

  

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

另外,看看旧帖子Are function static variables thread-safe in GCC?