|
Boost Users : |
Subject: [Boost-users] [interprocesss] managed_mapped_file mutex question
From: Andy Wiese (andyw_at_[hidden])
Date: 2010-03-18 11:55:09
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<void, segment_manager_t>
void_allocator_t;
typedef bip::allocator<char, segment_manager_t>
char_allocator_t;
typedef bip::basic_string<char, std::char_traits<char>,
char_allocator_t> char_string_t;
typedef bip::allocator<char_string_t, segment_manager_t>
char_string_allocator_t;
typedef bip::allocator<thing_t, segment_manager_t> thing_allocator_t;
typedef bip::set<thing_t, ThingLess, thing_allocator_t> thing_set_t;
typedef std::pair<const char_string_t, thing_set_t> map_value_t;
typedef bip::allocator<map_value_t, segment_manager_t>
map_value_allocator_t;
typedef bip::map< char_string_t, thing_set_t,
std::less<char_string_t>, map_value_allocator_t> index_map_t;
int main(int argc, char* argv[])
{
//fork(); // forking here will usually cause a bus error
int pid = getpid();
// find or create the mapped file
std::auto_ptr<shared_store_t> store(new
shared_store_t(bip::open_or_create, "/tmp/testindex", 1024*1024));
void_allocator_t allocator(store->get_segment_manager());
// find or create the index object
index_map_t* index = store->get_segment_manager()-
>find<index_map_t>("index").first;
if (!index) {
index = store->construct<index_map_t>("index")
(std::less<char_string_t>(), 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<<","<<i<< " "<< ba.what() <<
std::endl;
} catch(std::exception & e) {
std::cout << e.what() << std::endl;
} catch(...) {
std::cout << "some other exception" << std::endl;
}
}
std::cout << pid << " --------- End Round " << j << " --------- "
<<std::endl;
}
return 0;
}
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