CsT*_*mas 58 c++ static gcc initialization thread-safety
在示例代码中
void foo()
{
static Bar b;
...
}
Run Code Online (Sandbox Code Playgroud)
使用GCC编译是否可以保证b
以线程安全的方式创建和初始化?
在gcc的手册页中,找到了-fno-threadsafe-statics命令行选项:
不要发出额外的代码来使用C++ ABI中指定的例程来进行本地静态的线程安全初始化.您可以使用此选项在不需要线程安全的代码中略微减小代码大小.
这是否意味着,默认情况下,GCC的本地静态是线程安全的?所以没有理由明确保护,例如pthread_mutex_lock/unlock
?
如何编写可移植代码 - 如何检查编译器是否会添加其防护?或者关闭GCC的这个功能是否更好?
CB *_*ley 42
不,这意味着本地s 的初始化static
是线程安全的.
您肯定希望启用此功能.本地static
s的线程安全初始化非常重要.如果您通常需要线程安全访问本地static
s,那么您需要自己添加适当的防护.
sho*_*tsy 17
我们对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();
...
}
Run Code Online (Sandbox Code Playgroud)
唯一的解决方案是禁用gcc的这个功能.如果你需要你的代码是可移植的,那么你无论如何都不能依赖于特定gcc版本中添加的功能来保证线程安全.据说C++ 0x添加了线程安全的本地静态,直到那时这是非标准魔法,这使得你的代码不可移植,所以我建议反对它.如果您决定使用它,我建议您通过编写示例应用程序来验证您的gcc版本不会为此目的使用单个全局互斥锁.(线程安全的难度从即使是gcc也无法正确的事实中显而易见)