
This is a somewhat different take on the question I asked earlier
about interprocess mutexes in allocators.
I am using a default interprocess::managed_mapped_file to hold a index
for a multiprocess property store.
There is one object named "index" in the mapped file, which is an
interprocess::map.
The map holds an interprocess::set of fixed-length strings. (I had an
allocation problem with sets of string objects, but that's another
topic)
Many processes will both read and write this index map. Do the
interprocess:: containers provide the needed synchronization, or do I
need other synchronization mechanisms?
If I am reading the docs correctly, it seems to say that I don't need
additional synchronization if I am not adding/removing named objects.
However, my tests break with multiple processes. I don't know if I
just need my own synchronization or if a deeper problem is implied.
Following is the simple test I have been using. Works with one
process, breaks with two concurrent.
(os-x 10.5, boost trunk)
Thanks in advance for any advice!
Andy
-------------------------------------------------------
namespace bip = boost::interprocess;
typedef struct { char t[64]; } thing_t;
struct ThingLess {
bool operator()(thing_t const & lhs, thing_t const & rhs) const {
return (strcmp(lhs.t, rhs.t) < 0);
}
};
typedef bip::managed_mapped_file
shared_store_t;
typedef shared_store_t::segment_manager
segment_manager_t;
typedef bip::allocator
find
("index").first; if (!index) { index = store->construct ("index") (std::less (), allocator); assert(index); }
// add pairs to the map, find them, remove them. for (int j=0; j<1000; ++j) { for (int i=0; i<100; ++i) { try { std::ostringstream ks; ks << "key" << i; std::ostringstream ts; ts << "thing" << i; // look for thing in map char_string_t key(ks.str().c_str(), allocator); index_map_t::iterator foundIt = index->find(key); if (foundIt == index->end()) { // add thing to map thing_t thing; strcpy(thing.t,ts.str().c_str()); thing_set_t thingSet(ThingLess(), allocator); thingSet.insert(thing); map_value_t entry(key,thingSet); index->insert(entry); std::cout << pid << " Added " << key << std::endl; } // look again... foundIt = index->find(key); if (foundIt != index->end()) { if (ts.str() == foundIt->second.begin()->t) { std::cout << pid << " FOUND " << key << ":"<< foundIt-
second.begin()->t << std::endl; } else { std::cout << pid << " FAILED? " << key << ":"<< foundIt- second.begin()->t << std::endl; } } if (j%2) { // erase thing from map, every other pass just for some variety index->erase(key); std::cout << pid << " Erased " << key << std::endl; } } catch( bip::bad_alloc & ba ) { std::cout << "bad_alloc at " << j<<","<
return 0; }