#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace boost::interprocess; typedef managed_shared_memory::allocator::type char_allocator; typedef basic_string, char_allocator> shm_string; typedef shm_string KeyType; typedef shm_string MappedType; typedef std::pair ValueType; typedef allocator ShmemAllocator; typedef boost::unordered_map < KeyType , MappedType , boost::hash ,std::equal_to , ShmemAllocator> Hash; const char * const K_MUTEX_SUFFIX = "__MUTEX"; const char * const K_CONDITION_SUFFIX = "__CONDITION"; std::string MutexName(const std::string segment_name); std::string ConditionalName(const std::string segment_name); struct shm_remove { shm_remove(const std::string& segment_name) : segment_name_(segment_name) { const std::string mutex_name = MutexName(segment_name_); const std::string conditional_name = ConditionalName(segment_name_); shared_memory_object::remove( segment_name_.c_str() ); boost::interprocess::named_mutex::remove( mutex_name.c_str() ); boost::interprocess::named_condition::remove( conditional_name.c_str() ); } ~shm_remove() { const std::string mutex_name = MutexName(segment_name_); const std::string conditional_name = ConditionalName(segment_name_); shared_memory_object::remove( segment_name_.c_str() ); boost::interprocess::named_mutex::remove( mutex_name.c_str() ); boost::interprocess::named_condition::remove( conditional_name.c_str() ); } std::string segment_name_; private: // non copyable nor assignable ( could be movable though) shm_remove(const shm_remove&); shm_remove& operator=(shm_remove); }; std::string MutexName(const std::string segment_name) { std::stringstream str; str << "K_" << segment_name << K_MUTEX_SUFFIX; return str.str(); } std::string ConditionalName(const std::string segment_name) { std::stringstream str; str << "K_" << segment_name << K_CONDITION_SUFFIX; return str.str(); } int main() { // 23 + \0 const std::string key = "NokiaNokiaNokiaNokiaNok"; const std::string val = "NokiaNokiaNokiaNokiaNok_NokiaNokiaNokiaNokiaNok_NokiaNokiaNokiaNokiaNok_NokiaNokiaNokiaNokiaNok_NokiaNokiaNokiaNokiaNok_NokiaNokiaNokiaNokiaNok"; const std::string segment_name = "test segment numbero uno"; const std::string mutex_name = MutexName(segment_name); const std::string conditional_name = ConditionalName(segment_name); // remove shared memory on construction/destruction shm_remove remover(segment_name); // create shared memory managed_shared_memory segment(create_only, segment_name.c_str(), 4 * 1024); // construct a shared memory hash map // note that the first parameter is the initial bucket count and // after that, the hash function, the equality function and the allocator Hash * h = segment.construct("Hash") //object name ( 3, boost::hash(), std::equal_to() // , segment.get_allocator()); //allocator instance char_allocator sa(segment.get_allocator()); shm_string shared_key(key.c_str(), sa); shm_string shared_val(val.c_str(), sa); ValueType vt(shared_key, shared_val); h->insert(vt); { // open_only works regardless of key length // open_read_only segfaults at key byte len >= 24 managed_shared_memory segment(open_read_only, segment_name.c_str()); char_allocator sa(segment.get_allocator()); // SEGFAULT here depending on mode and key length shm_string shared_key(key.c_str(), sa); Hash::const_iterator i = h->find(shared_key); if(h->end() == i) { std::cerr << "no such key " << key << std::endl; return 1; } const ValueType& vt = *i; std::stringstream str; str << vt.second; std::cout << key << " => " << str.str() << std::endl; } return 0; }