Consider the following scenario. We have a C++ function with a static local variable:
void function()
{
static int variable = obtain();
//blahblablah
}
the function needs to be called from multiple threads concurrently, so we add a critical section to avoid concurrent access to the static local:
void functionThreadSafe()
{
CriticalSectionLockClass lock( criticalSection );
static int variable = obtain();
//blahblablah
}
but will this be enough? I mean there's some magic that makes the variable being initialized no more than once. So there's some service data maintained by the runtime that indicates whether each static local has already been initialized.
Will the critical section in the above code protect that service data as well? Is any extra protection required for this scenario?
Thread SafetyStatic variables are not thread safe. Instance variables do not require thread synchronization unless shared among threads. But, static variables are always shared by all the threads in the process. Hence, access to static variable is not thread safe.
Local variables are stored in each thread's own stack. That means that local variables are never shared between threads. That also means that all local primitive variables are thread safe.
C++ says that your static variable should only be initialized once - however C++ doesn't deal with threads(yet).
gcc(atleast on *nix systems) does the proper magic to safely guard multiple threads initializing such a static variable. According to this link, msvc does not - and in such a case you'll have to lock the initialization yourself.
Guarding the initialization with a critical section should protect all this - i.e. your functionThreadSafe() is ok - (unless obtain()
itself calls functionThreadSafe()
This blog article is worth a read in this regard.
Personally, to avoid surprises I'd try to rewrite this so you can initialize variable
yourself, once, before you create any threads - e.g.
static int variable = 0;
void init_variable() //call this once, at the start of main()
{
variable = obtain();
}
void function()
{
//use variable, lock if you write to it
}
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