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
isInitialized()
function instead of using the variable directly - would this guarantee a memory barrier? What if the function was declared inline
?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 your isInitialized()
function in another library and dynamically linking against it).
Two options that come to mind:
Declare initialized
as an atomic flag (in C++0x, you can use std::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.
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