Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to address thread-safety of service data used for maintaining static local variables in C++?

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?

like image 858
sharptooth Avatar asked Jun 02 '10 07:06

sharptooth


People also ask

Is static variable thread-safe in C?

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.

Are local variables in static method 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.


1 Answers

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
}
like image 57
nos Avatar answered Sep 30 '22 21:09

nos