Is static variable initialization thread-safe? 
Author Message
 Is static variable initialization thread-safe?

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?

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.

Mike



Wed, 10 Dec 2003 05:32:35 GMT  
 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



Wed, 10 Dec 2003 06:14:50 GMT  
 Is static variable initialization thread-safe?
To put is simply: first, think of function-statics as of globals. Second, think of classes as of structs. Third, think of constructors as of
simple functions. So, let's massage your code a bit:

CSomeStruct g_Struct;   // your struct

void IntializeCSomeStruct(CSomeStruct* pThis ); // your 'constructor

// your user function
void SomeFunction(void)
{
  IntializeCSomeStruct( &g_Struct ) ;

Quote:
}

Is the func above thread-safe? I think it's clear what's what now.


Wed, 10 Dec 2003 09:41:24 GMT  
 Is static variable initialization thread-safe?

Quote:

>To put is simply: first, think of function-statics as of globals. Second, think of classes as of structs. Third, think of constructors as of
>simple functions. So, let's massage your code a bit:

>CSomeStruct g_Struct;       // your struct

>void IntializeCSomeStruct(CSomeStruct* pThis ); // your 'constructor

>// your user function
>void SomeFunction(void)
>{
>  IntializeCSomeStruct( &g_Struct ) ;
>}

>Is the func above thread-safe? I think it's clear what's what now.

It's possible to imagine a compiler that ensures thread-safe
initialization of block scope statics, but I don't see how a compiler
could automatically make the above thread-safe. The OP was asking if
VC supported the former, if not by default, then through a switch.

--
Doug Harrison [VC++ MVP]
Eluent Software, LLC
http://www.eluent.com
Tools for Visual C++ and Windows



Thu, 11 Dec 2003 05:33:53 GMT  
 Is static variable initialization thread-safe?
Thanks for the helpful reply. I figured the compiler wouldn't help me out
here, but I wanted to find out for sure before fixing things that weren't
really broken. One queston: shouldn't the line that reads "static T*
volatile p;" be changed to "static T* volatile p = 0;"?



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.

> >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;
> }

> 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



Sat, 13 Dec 2003 00:16:11 GMT  
 Is static variable initialization thread-safe?
Actually, to prevent the initialization from happening every time the
function is called, the compiler already must generate code more like this:

CSomeStruct g_Struct; // your struct
bool g_Initialized = false;

 void IntializeCSomeStruct(CSomeStruct* pThis ); // your 'constructor

 // your user function
 void SomeFunction(void)
 {
    if (!g_Initialized)
    {
       IntializeCSomeStruct( &g_Struct ) ;
       g_Initialized = true;
    }
 }

My question was whether it was also able to protect the initialization
section to make it thread-safe.

Mike Glassford
StayinFront, Inc.


Quote:
> To put is simply: first, think of function-statics as of globals. Second,

think of classes as of structs. Third, think of constructors as of
Quote:
> simple functions. So, let's massage your code a bit:

> CSomeStruct g_Struct; // your struct

> void IntializeCSomeStruct(CSomeStruct* pThis ); // your 'constructor

> // your user function
> void SomeFunction(void)
> {
>   IntializeCSomeStruct( &g_Struct ) ;
> }

> Is the func above thread-safe? I think it's clear what's what now.



Sat, 13 Dec 2003 00:12:46 GMT  
 Is static variable initialization thread-safe?

Quote:

>Thanks for the helpful reply. I figured the compiler wouldn't help me out
>here, but I wanted to find out for sure before fixing things that weren't
>really broken. One queston: shouldn't the line that reads "static T*
>volatile p;" be changed to "static T* volatile p = 0;"?

There's no need to do that. Static duration variables are
zero-initialized at program startup before any other initialization
takes place, so p is NULL upon first entry to that function.

--
Doug Harrison [VC++ MVP]
Eluent Software, LLC
http://www.eluent.com
Tools for Visual C++ and Windows



Sat, 13 Dec 2003 04:12:32 GMT  
 Is static variable initialization thread-safe?
Quote:

> Actually, to prevent the initialization from happening every time the
> function is called, the compiler already must generate code more like this:

Right.

Quote:
> My question was whether it was also able to protect the initialization
> section to make it thread-safe.

The answer is no. C++ is not aware of any threads, it's the notion that
belongs outside of the C++ language. Other languages may be different,
but C++ is that way. So, anything MT is up to you to handle explicitly,
with your own code, that's a simple heuristic that you can use.


Sat, 13 Dec 2003 04:52:49 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. initialization of static variables ?

2. Is static variable initialization once is not enough........???

3. allocation and initialization of static variables

4. Initialization order for global and static variables

5. static member variable initialization

6. Thread Safe Events and Static Methods

7. Are static methods thread safe?

8. Call to local static object constructor not thread-safe

9. Why is function static singleton not thread-safe?

10. How to make static methods thread safe

11. Thread-safe Local Variables

12. global variables thread-safe

 

 
Powered by phpBB® Forum Software