Boost C++ Libraries: Ticket #12476: Using named_condition_any with a readers-writer lock https://svn.boost.org/trac10/ticket/12476 <p> I am trying to use condition variables to signify updated data in a managed_shared_memory segment. I have one "writer" and multiple "readers" of the shared state, so I am using a readers-writer lock. </p> <p> Unfortunately, although the code compiles, the reader processes are never awakened from wait() and block forever. </p> <p> It seems named_condition_any may be incompatible with named_sharable_mutex, scoped_lock, sharable_lock, or some combination of the three. Attached is a producer and consumer process that demonstrates the behavior. Run the producer first, then run the consumer. </p> <p> Expected behavior: consumer process will print values for "copy of int" every 2 seconds (as producer updates) </p> <p> Observed behavior: consumer process blocks on named_condition_any::wait() and never awakens. </p> <p> Including the code here in case the attachments don't go through: </p> <p> PRODUCER: </p> <pre class="wiki">#include &lt;thread&gt; #include &lt;chrono&gt; #include &lt;iostream&gt; #include &lt;boost/interprocess/sync/scoped_lock.hpp&gt; #include &lt;boost/interprocess/sync/named_mutex.hpp&gt; #include &lt;boost/interprocess/sync/named_sharable_mutex.hpp&gt; #include &lt;boost/interprocess/sync/sharable_lock.hpp&gt; #include &lt;boost/interprocess/sync/named_condition_any.hpp&gt; #include &lt;boost/interprocess/managed_shared_memory.hpp&gt; namespace bi = boost::interprocess; using SharedMutex = bi::named_sharable_mutex; using ReadLock = bi::sharable_lock&lt;SharedMutex&gt;; using WriteLock = bi::scoped_lock&lt;SharedMutex&gt;; using NewEntryCondition = bi::named_condition_any; constexpr char SHM_NAME[] = "shared_mem"; constexpr char MUT_NAME[] = "shm_mut"; constexpr char COND_NAME[] = "shm_cond"; constexpr char CUR_INT_NAME[] = "shm_int"; int main(int argc, char *argv[]) { // Remove the shared mem, condition variable, mutex struct shm_remove { shm_remove() { bi::shared_memory_object::remove( SHM_NAME ); } ~shm_remove() { bi::shared_memory_object::remove( SHM_NAME ); } } remover; struct mut_remove { mut_remove() { SharedMutex::remove(MUT_NAME); } ~mut_remove() { SharedMutex::remove(MUT_NAME); } } mut_remover; struct cond_remove { cond_remove() { NewEntryCondition::remove(COND_NAME); } ~cond_remove() { NewEntryCondition::remove(COND_NAME); } } cond_remover; // Create the shared mem, condition variable, mutex bi::managed_shared_memory segment(bi::create_only, SHM_NAME, 2*65536); SharedMutex sh_mut(bi::create_only, MUT_NAME); NewEntryCondition sh_cond(bi::create_only, COND_NAME); int&amp; shared_int = *segment.construct&lt;int&gt;("shared_int")(0); for (int i=0;;i++) { std::this_thread::sleep_for(std::chrono::seconds(2)); { WriteLock w_lock( sh_mut ); shared_int = i; std::cout &lt;&lt; "set shared_int to: " &lt;&lt; shared_int &lt;&lt; std::endl; sh_cond.notify_all(); } } return 0; } </pre><p> CONSUMER: </p> <pre class="wiki">#include &lt;thread&gt; #include &lt;chrono&gt; #include &lt;iostream&gt; #include &lt;boost/interprocess/sync/scoped_lock.hpp&gt; #include &lt;boost/interprocess/sync/named_mutex.hpp&gt; #include &lt;boost/interprocess/sync/named_sharable_mutex.hpp&gt; #include &lt;boost/interprocess/sync/sharable_lock.hpp&gt; #include &lt;boost/interprocess/sync/named_condition_any.hpp&gt; #include &lt;boost/interprocess/managed_shared_memory.hpp&gt; namespace bi = boost::interprocess; using SharedMutex = bi::named_sharable_mutex; using ReadLock = bi::sharable_lock&lt;SharedMutex&gt;; using WriteLock = bi::scoped_lock&lt;SharedMutex&gt;; using NewEntryCondition = bi::named_condition_any; constexpr char SHM_NAME[] = "shared_mem"; constexpr char MUT_NAME[] = "shm_mut"; constexpr char COND_NAME[] = "shm_cond"; constexpr char CUR_INT_NAME[] = "shm_int"; int main(int argc, char *argv[]) { // Open the shared mem, condition variable, mutex bi::managed_shared_memory segment(bi::open_only, SHM_NAME); SharedMutex sh_mut(bi::open_only, MUT_NAME); NewEntryCondition sh_cond(bi::open_only, COND_NAME); int&amp; shared_int = *segment.find&lt;int&gt;("shared_int").first; int copy_of_int = -1; for (int i=0;;i++) { { ReadLock r_lock( sh_mut ); std::cout &lt;&lt; "calling named_condition_any::wait()" &lt;&lt; std::endl; sh_cond.wait( r_lock, [&amp;shared_int, &amp;copy_of_int]() { std::cout &lt;&lt; "checking predicate..." &lt;&lt; std::endl; return (copy_of_int &lt; shared_int); }); copy_of_int = shared_int; std::cout &lt;&lt; "copy of int = " &lt;&lt; copy_of_int &lt;&lt; std::endl; } } return 0; } </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/12476 Trac 1.4.3 Chris Evans <chris.evans@…> Wed, 21 Sep 2016 14:02:04 GMT attachment set https://svn.boost.org/trac10/ticket/12476 https://svn.boost.org/trac10/ticket/12476 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">producer.cpp</span> </li> </ul> Ticket Chris Evans <chris.evans@…> Wed, 21 Sep 2016 14:02:15 GMT attachment set https://svn.boost.org/trac10/ticket/12476 https://svn.boost.org/trac10/ticket/12476 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">consumer.cpp</span> </li> </ul> Ticket Chris Evans <chris.evans@…> Wed, 21 Sep 2016 14:02:28 GMT attachment set https://svn.boost.org/trac10/ticket/12476 https://svn.boost.org/trac10/ticket/12476 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">CMakeLists.txt</span> </li> </ul> Ticket