Date: Wed, 19 Jun 2013 22:05:32 +0200 From: Ion Gazta?aga <igaztanaga@gmail.com> To: boost-users@lists.boost.org Subject: Re: [Boost-users] Mutex synchronised wrapper class for boost::interprocess shared memory vector of strings Message-ID: <51C20F0C.8090408@gmail.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed El 18/06/2013 16:28, Riskybiz escribi?:
I'm trying to write a wrapper class in C++ to give mutex synchronised interprocess access to a shared memory vector of strings. This is my first foray into boost::interprocess and allocators are proving something of a mystery.
Is anyone able to see why on compilation I get the error:
When you build any container in shared memory it must be constructed with an allocator. Change your push function to (not charallocator is passed to MyShmString): void push(const std::string & in) { CharAllocator charallocator(m_segment->get_segment_manager()); scoped_lock<named_mutex> lock(*m_mutex); MyShmString inStr(in.c_str(), charallocator); sharedSegmentVector->push_back(inStr); } Best, Ion Thanks for the reply Ion. I'm now having trouble reading from the vector in the shared memory. I get an exception when calling read(0) or read(1). What I'm trying to do is read "testing testing 123" from the first element of the sharedSegmentVector. Is it necessary to use some particular type conversion technique in the reader function to access a sharedSegmentVector string element? Any help to get this working is much appreciated; I've been trying for more than a month to get to this point! Code below..... Thanks Riskybiz #ifndef SHARED_MEMORY_WRAPPER_H//if not defined already #define SHARED_MEMORY_WRAPPER_H//then define it #include <boost/interprocess/managed_shared_memory.hpp> #include <boost/interprocess/containers/vector.hpp> #include <boost/interprocess/containers/string.hpp> #include <boost/interprocess/allocators/allocator.hpp> #include <boost/interprocess/sync/named_mutex.hpp> using namespace boost::interprocess; class SharedMemoryWrapper { public: SharedMemoryWrapper(const std::string &name, bool server) : m_name(name), m_server(server) { if (server) { named_mutex::remove("named_mutex"); shared_memory_object::remove(m_name.c_str()); //Create shared memory managed_shared_memory m_segment(create_only, m_name.c_str(), 10000); //Create allocators CharAllocator charallocator(m_segment.get_segment_manager()); StringAllocator stringallocator(m_segment.get_segment_manager()); //This string is in only in this process (the pointer pointing to the //buffer that will hold the text is not in shared memory). //But the buffer that will hold "this is my text" is allocated from //shared memory MyShmString mystring(charallocator); mystring = "testing testing 1 2 3"; //This vector is fully constructed in shared memory. All pointers //buffers are constructed in the same shared memory segment //This vector can be safely accessed from other processes. MyShmStringVector *sharedSegmentVector = m_segment.construct<MyShmStringVector>("sharedSegmentVector")(stringallocato r); sharedSegmentVector->push_back(mystring); } else { //Open the shared segment managed_shared_memory m_segment(open_only, name.c_str()); //Find the vector using the c-string name and open it MyShmStringVector *sharedSegmentVector = m_segment.find<MyShmStringVector>("sharedSegmentVector").first; } m_mutex = new named_mutex(open_or_create, "named_mutex"); } ~SharedMemoryWrapper() { if (m_server) { named_mutex::remove("named_mutex"); //Destroy the vector from the managed_shared_memory m_segment->destroy_ptr(sharedSegmentVector);//This will free all strings that the vector contains m_segment->destroy<MyShmStringVector>("sharedSegmentVector");//Destroy the vector //Is it necessary to destroy the allocators here? //Remove the managed_shared_memory; this may fail if the memory does not exist or is mapped or opened by another process shared_memory_object::remove(m_name.c_str()); } delete m_mutex; delete m_segment; } //Writer void write(const std::string &in) { CharAllocator charallocator(m_segment->get_segment_manager()); scoped_lock<named_mutex> lock(*m_mutex); MyShmString shmStr(in.c_str(), charallocator); sharedSegmentVector->push_back(shmStr); } //Reader std::string read(long index) { CharAllocator charallocator(m_segment->get_segment_manager()); scoped_lock<named_mutex> lock(*m_mutex); MyShmString shmStr(sharedSegmentVector->at(index), charallocator); std::string stdStr = std::string(shmStr.begin(), shmStr.end()); return stdStr; } private: //Typedefs typedef boost::interprocess::allocator<char, managed_shared_memory::segment_manager> CharAllocator; typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> MyShmString; typedef boost::interprocess::allocator<MyShmString, managed_shared_memory::segment_manager> StringAllocator; typedef boost::interprocess::vector<MyShmString, StringAllocator> MyShmStringVector; bool m_server; std::string m_name; managed_shared_memory *m_segment; MyShmStringVector *sharedSegmentVector; named_mutex *m_mutex; };//class #endif//header guard