In the example code
void foo() { static Bar b; ... }
compiled with GCC is it guaranteed that b
will be created and initialized in a thread-safe manner ?
In gcc's man page, found the -fno-threadsafe-statics command line option:
Do not emit the extra code to use the routines specified in the C++ ABI for thread-safe initialization of local statics. You can use this option to reduce code size slightly in code that doesn't need to be thread-safe.
Does it mean, that local statics are thread-safe by default with GCC ? So no reason to put explicit guarding e.g. with pthread_mutex_lock/unlock
?
How to write portable code - how to check if compiler will add its guards ? Or is it better to turn off this feature of GCC ?
So yes, you're safe.
Static variables are indeed shared between threads, but the changes made in one thread may not be visible to another thread immediately, making it seem like there are two copies of the variable.
[Note: After this article was written, the C++ standard has been revised. Starting in C++11, scoped static initialization is now thread-safe, but it comes with a cost: Reentrancy now invokes undefined behavior.]
No, it means that the initialization of local static
s is thread-safe.
You definitely want to leave this feature enabled. Thread-safe initialization of local static
s is very important. If you need generally thread-safe access to local static
s then you will need to add the appropriate guards yourself.
We had serious issues with the locking code generated by GCC 3.4 to protect local static initialization. That version used a global shared mutex to protect all and any static initialization which lead to a deadlock in our code. We had a local static variable initialized from a result of a function, which started another thread, which created a local static variable. Pseudocode:
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(); ... }
The only solution was to disable this feature of gcc. If you need your code to be portable , which we did, you can not anyway depend on a feature added in a specific gcc version for thread safety. Supposedly C++0x adds thread-safe local statics, until then this is non-standard magic which makes your code non-portable, so I am advising against it. If you decide to use it, I suggest you validate that your gcc version does not use a single global mutex for this purpose by writing a sample application. (The difficulty of thread-safety is apparent from the fact that even gcc can not get it right)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With