2013-12-18 25 views
3

IMAGIN这样的:通过C函数调用线程安全的静态初始化?

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

这是初始化线程?

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

+2

这不是合法的C代码。但是如果你在谈论C++而不是C,那么它肯定不是线程安全的。我不确定C++ 11是怎么说的,但C++ 03和更早版本根本没有提到线程。从我从各种编译器看到的生成代码中,他们不会在变量初始化的基础上添加任何同步原语。 –

+1

@AdamRosenfield它在gcc(C++)中是线程安全的,C++ 11要求它是 – nos

+0

愚蠢的MSVC ....我说的是纯粹的C但是我只是在Windows上测试了这个,没有错误。但是我忘记了这对C++标准来说是不可靠的,因为MSVC期望C代码。不管怎么说,还是要谢谢你。 – dhein

回答

3

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

从C99§6.7.8/ 4:

所有在对于具有静态存储期限为常量表达式或字符串文字的对象的初始化表达式。

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

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

相关问题