Boost logo

Boost Users :

Subject: [Boost-users] [thread] memory synchronization multiple mutexes
From: firespot (firespot71_at_[hidden])
Date: 2014-08-28 08:53:18


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


    // wait until Ptr has been reset to 0
     boost::unique_lock<boost::mutex> Lock(m1);
     while (Ptr != 0)

and another function:

void g()
     boost::unique_lock<boost::mutex> Lock(m2);
     while (run == 0)

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

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?


Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at