关于在多线程环境中使用静态const变量

jya*_*ard 6 c++ thread-safety

我试图了解潜在的情况以及它是否可能是一个问题.

所以我有一个当前线程安全的静态函数.功能如下:

static thread_safe_func()
{
    ... process
}
Run Code Online (Sandbox Code Playgroud)

现在在这个函数中,我添加以下内容:

static thread_safe_func()
{
  static const Class::NonThreadSafeClassName() *array[16] = {
    Class::NonThreadSafeClassName(),
    Class::NonThreadSafeClassName(),
    Class::NonThreadSafeClassName(),
    Class::NonThreadSafeClassName(),
    Class::NonThreadSafeClassName(),
    Class::NonThreadSafeClassName(),
    Class::NonThreadSafeClassName(),
  }
  ... code continues here
}
Run Code Online (Sandbox Code Playgroud)

现在它本身是线程安全的吗?数组将在应用程序的整个生命周期内初始化一次,因此一旦函数thread_safe_func()被调用并完全运行,我希望这是线程安全的.

问题显然是在第一次调用期间可能发生的情况,在线程调用thread_safe_func()的情况下会发生什么,const数组的初始化发生,但在初始化完成之前,另一个线程正在调用thread_safe_func().

会改为:

static ClassMutex lock = ClassMutex()

static thread_safe_func()
{
  lock.Lock()
  static const Class::NonThreadSafeClassName() *array[16] = {
    Class::NonThreadSafeClassName(),
    Class::NonThreadSafeClassName(),
    Class::NonThreadSafeClassName(),
    Class::NonThreadSafeClassName(),
    Class::NonThreadSafeClassName(),
    Class::NonThreadSafeClassName(),
    Class::NonThreadSafeClassName(),
  }
  lock.Unlock()
  ... code continues here
}
Run Code Online (Sandbox Code Playgroud)

是否值得并保证此代码现在是线程安全的?

Bra*_*vic 5

C++ 03下,既不......

void foo() {
  static your_variable = ...;
}
Run Code Online (Sandbox Code Playgroud)

...也不...

void foo() {
    lock.Lock();
    static your_variable = ...;
    lock.Unlock();
}
Run Code Online (Sandbox Code Playgroud)

......是线程安全的.

第一个不是线程安全的,因为标准没有提到第二个线程在第一个线程仍在执行初始化时进入该函数.事实上,标准根本没有线程的概念.

第二个不是线程安全的,因为初始化发生在执行流程进入函数(第一次)时,即之前 lock.Lock().


C++ 11中,本地静态变量的初始化是线程安全的.

  • 关于第二点的附加信息,来自规范(第6.7节):"具有静态存储持续时间的本地实体的常量初始化(3.6.2)(如果适用)在首次输入其块之前执行." (2认同)
  • 但是`void foo(){lock.Lock(); {static your_variable = ...;} lock.Unlock(); }安全吗? (2认同)