In a code review today, I stumbled across the following bit of code (slightly modified for posting):
while (!initialized)
{
// The thread can start before the constructor has finished initializing the object.
// Can lead to strange behavior.
continue;
}
This is the first few lines of code that runs in a new thread. In another thread, once initialization is complete, it sets initialized to true.
I know that the optimizer could turn this into an infinite loop, but what’s the best way to avoid that?
volatile– considered harmful- calling an
isInitialized()function instead of using the variable directly – would this guarantee a memory barrier? What if the function was declaredinline?
Are there other options?
Edit:
Should have mentioned this sooner, but this is portable code that needs to run on Windows, Linux, Solaris, etc. We use mostly use Boost.Thread for our portable threading library.
Calling a function won’t help at all; even if a function is not declared
inline, its body can still be inlined (barring something extreme, like putting yourisInitialized()function in another library and dynamically linking against it).Two options that come to mind:
Declare
initializedas an atomic flag (in C++0x, you can usestd::atomic_flag; otherwise, you’ll want to consult the documentation for your threading library for how to do this)Use a semaphore; acquire it in the other thread and wait for it in this thread.