GCC中的函数静态variables是否是线程安全的?
在示例代码中
void foo() { static Bar b; ... }
使用GCC编译是保证b
将被创build和线程安全的方式初始化?
在gcc的手册页中,find了-fno-threadsafe-statics命令行选项:
不要发出额外的代码来使用C ++ ABI中指定的用于本地静态线程安全初始化的例程。 您可以使用此选项在不需要线程安全的代码中稍微减less代码大小。
-
这是否意味着,本地静态在GCC默认情况下是线程安全的? 那么没有理由明确地捍卫,例如与
pthread_mutex_lock/unlock
? -
如何编写可移植代码 – 如何检查编译器是否会添加其警卫? 还是closuresGCC的这个function更好?
-
不,这意味着本地
static
的初始化是线程安全的。 -
你一定要离开这个function启用。 本地
static
的线程安全初始化非常重要。 如果你通常需要线程安全的访问本地static
那么你将需要自己添加适当的守卫。
我们对GCC 3.4生成的locking代码有严重的问题,以保护本地静态初始化。 该版本使用全局共享互斥体来保护所有静态初始化,并导致代码中的死锁。 我们有一个本地静态variables,从一个函数的结果初始化,它启动了另一个线程,它创build了一个本地静态variables。 伪代码:
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(); ... }
唯一的解决办法是禁用gcc的这个function。 如果你需要你的代码是可移植的,我们所做的,你不能依赖于在特定的gcc版本中添加的function来保证线程安全。 据说C ++ 0x增加了线程安全的本地静态,直到这是非标准的魔法,这使得你的代码不可移植,所以我build议反对它。 如果你决定使用它,我build议你通过编写一个示例应用程序validation你的gcc版本没有使用一个单一的全局互斥体来达到这个目的。 (线程安全的困难从甚至gcc不能正确的事实中是显而易见的)
我认为这个关键词是
本地静态线程安全初始化
我读这意味着它只是一个线程安全的静态初始化。 静态的一般使用不会是线程安全的。
这不是马上回答你的问题( Charles已经这样做了 ),但是我认为是时候再次发布一篇文章的链接了。 它揭示了全局variables的初始化,应该在每个尝试在multithreading环境中使用static
variables的人阅读和理解。