Re: Should I use mutex in this context?
On Sat, 25 Oct 2008 08:54:47 -0700 (PDT), swtbase@gmail.com wrote:
Hi,
My program has two threads; one main thread and other working thread.
My main thread asks the worker thread to terminate if system is
shutting down by making true a boolean value which is a global shared
resource. The main thread only writes to the global value and the
worker thread only reads the same value. In this context, is mutex use
necessary?
That's a complex question. On a multiprocessor system with a weakly-ordered
memory system, the result of the write may be indefinitely delayed from the
perspective of a reader executing on another CPU. The solution to that is
to use the memory barrier instructions, which are implicit when you use a
mutex; using a mutex would be the recommended approach. On a
strongly-ordered system such as x86, that's not a concern, but you have to
worry about compiler optimizations, which are also an issue for the former.
For example, if you're checking the bool in a loop that makes no opaque
function calls, the compiler may determine no one can modify the bool, so
it can read its value once and never again. Again, you can solve that
problem with a mutex, or you can cheat and declare the bool volatile. The
problem with volatile is that it doesn't provide the ordering and memory
visibility guarantees associated for the mutex, which in the very limited
context you described, may not matter. The safest, most foolproof, most
portable approach is to use a mutex. On Windows, you could also use an
event object, which can help provide an escape valve for functions such as
WaitForMultipleObjects. For more on this, see the following page,
particularly questions 2 and later:
http://members.cox.net/doug_web/threads.htm
Finally, I should note that VC2005 and later imbue volatile with memory
barrier and ordering semantics, probably because there's so much bad code
written with volatile they had little choice but to try to band-aid it so
it would work slightly more reliably on x86 systems and continue to sort of
work on weakly-ordered SMP memory systems. I don't know of any other
compiler that does this for volatile, which even in VC2005 and later, does
not replace the vast majority of mutex usage. For example, "x = x+1;" does
not become "safe" in VC2005 just because you declare x volatile. You need a
mutex here to make the whole read/modify/update cycle atomic. (Of course,
for this simple example, you could use InterlockedIncrement, but it gets
the point across in a concise way.)
--
Doug Harrison
Visual C++ MVP