|
Boost Users : |
Subject: [Boost-users] [thread] memory synchronization multiple mutexes
From: firespot (firespot71_at_[hidden])
Date: 2014-08-28 08:53:18
Hi,
How does memory synchronization and visibility behave when multiple
mutexes are involved?
I have two groups of threads (boost::thread_group) and two mutexes
(boost::mutex m1, boost::mutex m2) + associated condition variables,
with each thread group being responsible to write to some variables
(here Ptr, run) and consistently using "its" mutex for locking.
However there is a piece of code that looks - much simplified - like this:
void f()
{
{
boost::unique_lock<boost::mutex> Lock(m1);
Ptr = someAddress; // set the Ptr from 0 to some memory address
}
{
boost::unique_lock<boost::mutex> Lock(m2);
run = 1; // was 0, inform that execution can proceed
condVar2.notify_all();
}
...
// wait until Ptr has been reset to 0
{
boost::unique_lock<boost::mutex> Lock(m1);
while (Ptr != 0)
condVar1.wait(Lock);
}
}
and another function:
void g()
{
{
boost::unique_lock<boost::mutex> Lock(m2);
while (run == 0)
condVar2.wait(Lock);
}
// run the execution, e.g.
std::copy(Ptr, Ptr + 100, Target);
// finally all finished, signal back that Ptr is not needed any more
{
boost::unique_lock<boost::mutex> Lock(m1);
Ptr = 0;
condVar1.notify_all();
}
}
f() is only invoked from a thread of the first group, and g() only from
a thread of the second group. Whenever Ptr might get changes the first
mutex (m1) and its associated condition-variable is used, and whenver
run might get changed the second mutex and its associated conditional
variable is used. The control flow guarantees that run is not set to 1
prior to Ptr being set, and thus in g() the "running" itself (here the
std::copy) cannot commence earlier. However, what puzzles me now: I used
a different mutex for setting Ptr and setting/checking run. Does this
have any impact whatsoever on memory visibility across the threads in
the two thread-groups? Specifically, is it always guaranteed that when
g() continues its execution (because run == 1) that it must see the
correct value of Ptr (a non-NULL value)? Or is it possible that it still
sees 0 and I'd have to make a separate locking involving m1 to guarantee
a proper read for Ptr as anything written under a lock of m1 is also
only guaranteed to be later properly read if the locking also used m1?
thanks!
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net