
Is static variable initialization thread-safe?
Quote:
>If I have code like this...
> void SomeFunction(void)
> {
> static CSomeClass obj;
> ...
> }
>... then since obj is declared as a static variable, the compiler inserts
>code to make sure it is only initialized the first time the function
>SomeFunction is executed. If the function is called in a multi-threaded
>environment, is this compiler-generated code thread-safe? In other words, if
>the function is called on two threads simultaneously, will one function wait
>until the other finishes initializing the static variable? Is there a
>compiler option I can set to make this work?
No to all.
Quote:
>If not, how do I handle this? I can't simply do this (using the MFC
>multi-threading classes)...
> void SomeFunction(void)
> {
> static CCriticalSection cs;
> CSingleLock lock(&cs, true);
> static CSomeClass obj;
> ...
> }
>...because the static variable cs has the same initialization problem as
>obj.
So declare cs global and don't start any threads during the creation
of global objects, which in VC, is completed before entry to main().
Here's a sketch of how I do it:
T& get()
{
// This is often called the "double-checked locking pattern",
// and it's a way to initialize singletons in a thread-safe
// way.
static T* volatile p;
if (!p)
{
// cs is a global CritSec.
CritSec::Lock lock(cs);
if (!p)
{
p = new T;
// Or if you want the T to be destroyed at program exit:
static T x;
p = &x;
}
}
return *p;
Quote:
}
This way you avoid the overhead of locking a critical section on each
access. (NB: The above is not correct for a weakly ordered memory
subsystem, but you don't have to worry about that for x86 CPUs.)
--
Doug Harrison [VC++ MVP]
Eluent Software, LLC
http://www.eluent.com
Tools for Visual C++ and Windows