是否在C中通过函数调用线程安全进行静态初始化?

时间:2013-12-18 22:43:25

标签: c static thread-safety

想象一下:

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

这个初始化线程是否安全?

即使QuestionTag()是线程安全的,如果第一个线程运行该函数而另一个线程调用此行,会发生什么。是否会检测到该功能只会被执行一次?或者这只是多线程的一个坏主意?

1 个答案:

答案 0 :(得分:3)

这不是合法的C代码,因为C要求静态变量的初始化器是编译时常量。因此初始化可以在程序加载时发生,在任何线程有机会启动之前,因此那里不存在竞争条件。

来自C99§6.7.8/ 4:

  

具有静态存储持续时间的对象的初始值设定项中的所有表达式都应为常量表达式或字符串文字。

Visual Studio可能允许非常量作为非标准扩展,但为此,所有赌注都是关闭的。检查其文档和/或其生成的汇编代码,看它是否是线程安全的。

对于允许使用非常量初始值设定项的C ++,请参阅问题Is initialization of local static function-object thread-safe?。简短的回答:是的,在C ++ 11中,在C ++ 03及更早版本中没有(在标准中没有提到线程),尽管编译器如果选择它们仍然可以使它成为线程安全的。