Are function static variables thread-safe in GCC?
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 ?
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 localstatic
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)
This is not really answering your questions straight away (Charles already did that), but I think it's time to post a link to this article again. It throws light on the initialization of globals and should be read and understood by everyone attempting to use static
variables in a multi-threaded environment.
I think that the key phrase is
... thread-safe initialization of local statics.
I read this as meaning that it is only initialization of statics that would be done in a thread-safe way. General use of statics would not be thread-safe.