Subject: [Boost-bugs] [Boost C++ Libraries] #12476: Using named_condition_any with a readers-writer lock
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2016-09-21 14:01:32
#12476: Using named_condition_any with a readers-writer lock
----------------------------------------------+--------------------------
Reporter: Chris Evans <chris.evans@â¦> | Owner: igaztanaga
Type: Bugs | Status: new
Milestone: To Be Determined | Component: interprocess
Version: Boost 1.58.0 | Severity: Problem
Keywords: interprocess named_condition_any |
----------------------------------------------+--------------------------
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.
Unfortunately, although the code compiles, the reader processes are never
awakened from wait() and block forever.
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.
Expected behavior: consumer process will print values for "copy of int"
every 2 seconds (as producer updates)
Observed behavior: consumer process blocks on named_condition_any::wait()
and never awakens.
Including the code here in case the attachments don't go through:
PRODUCER:
{{{
#include <thread>
#include <chrono>
#include <iostream>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/named_sharable_mutex.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <boost/interprocess/sync/named_condition_any.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
namespace bi = boost::interprocess;
using SharedMutex = bi::named_sharable_mutex;
using ReadLock = bi::sharable_lock<SharedMutex>;
using WriteLock = bi::scoped_lock<SharedMutex>;
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& shared_int = *segment.construct<int>("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 << "set shared_int to: " << shared_int << std::endl;
sh_cond.notify_all();
}
}
return 0;
}
}}}
CONSUMER:
{{{
#include <thread>
#include <chrono>
#include <iostream>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/named_sharable_mutex.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <boost/interprocess/sync/named_condition_any.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
namespace bi = boost::interprocess;
using SharedMutex = bi::named_sharable_mutex;
using ReadLock = bi::sharable_lock<SharedMutex>;
using WriteLock = bi::scoped_lock<SharedMutex>;
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& shared_int = *segment.find<int>("shared_int").first;
int copy_of_int = -1;
for (int i=0;;i++) {
{
ReadLock r_lock( sh_mut );
std::cout << "calling named_condition_any::wait()" <<
std::endl;
sh_cond.wait(
r_lock,
[&shared_int, ©_of_int]() {
std::cout << "checking predicate..." << std::endl;
return (copy_of_int < shared_int);
});
copy_of_int = shared_int;
std::cout << "copy of int = " << copy_of_int << std::endl;
}
}
return 0;
}
}}}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/12476> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:20 UTC