Boost, shared memory and vectors

I need to split a stack of lines between processes (possibly more complex objects in the future). I decided to use boost :: interprocess, but I can't get it to work. I am sure because I do not understand anything. I followed suit, but I would really appreciate it if someone who had experience using this library could look at my code and tell me what happened. The problem is that it works, but after several iterations I get all kinds of exceptions both in the reading process and in the writing process. Here is a simplified version of my implementation:

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()); m_segment = new managed_shared_memory (create_only,name.c_str(),65536); m_stackAllocator = new StringStackAllocator(m_segment->get_segment_manager()); m_stack = m_segment->construct<StringStack>("MyStack")(*m_stackAllocator); } else { m_segment = new managed_shared_memory(open_only ,name.c_str()); m_stack = m_segment->find<StringStack>("MyStack").first; } m_mutex = new named_mutex(open_or_create, "named_mutex"); } ~SharedMemoryWrapper() { if (m_server) { named_mutex::remove("named_mutex"); m_segment->destroy<StringStack>("MyStack"); delete m_stackAllocator; shared_memory_object::remove(m_name.c_str()); } delete m_mutex; delete m_segment; } void push(const std::string & in) { scoped_lock<named_mutex> lock(*m_mutex); boost::interprocess::string inStr(in.c_str()); m_stack->push_back(inStr); } std::string pop() { scoped_lock<named_mutex> lock(*m_mutex); std::string result = ""; if (m_stack->size() > 0) { result = std::string(m_stack->begin()->c_str()); m_stack->erase(m_stack->begin()); } return result; } private: typedef boost::interprocess::allocator<boost::interprocess::string, boost::interprocess::managed_shared_memory::segment_manager> StringStackAllocator; typedef boost::interprocess::vector<boost::interprocess::string, StringStackAllocator> StringStack; bool m_server; std::string m_name; boost::interprocess::managed_shared_memory * m_segment; StringStackAllocator * m_stackAllocator; StringStack * m_stack; boost::interprocess::named_mutex * m_mutex; }; 

EDIT Edited to use named_mutex. The source code used interprocess_mutex, which is incorrect, but this is not a problem.

EDIT2 I should also note that everything works to a certain extent. The writing process may pop out several small lines (or one very large line) before the reader breaks. The reader breaks in such a way that the line m_stack-> begin () does not belong to a valid line. This is trash. And then further execution throws an exception.

EDIT3 I changed the class to use boost :: interprocess :: string, not std :: string. However, the reader does not work with the wrong memory address. Here is the reader / writer

 //reader process SharedMemoryWrapper mem("MyMemory", true); std::string myString; int x = 5; do { myString = mem.pop(); if (myString != "") { std::cout << myString << std::endl; } } while (1); //while (myString != ""); //writer SharedMemoryWrapper mem("MyMemory", false); for (int i = 0; i < 1000000000; i++) { std::stringstream ss; ss << i; //causes failure after few thousand iterations //ss << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" << i; //causes immediate failure mem.push(ss.str()); } return 0; 
+6
c ++ boost ipc interprocess
source share
2 answers

There are a few things that have fallen on me about your implementation. One of them is the use of a pointer to a named mutex object, while the documentation of most accelerator libraries tends to lean back so as not to use a pointer. This leads me to ask for a link to a piece of the program you worked with in creating my own test case, because I had similar misadventures, and sometimes the only way out is to return to the sample and work forward one step at a time until I come across with change.

Another thing that seems dubious is allocating a 65k block for shared memory, and then in your test code, looping up to 1,000,000,000, pushing a line onto your stack each iteration.

With a modern PC capable of executing 1000 instructions per microsecond or more, and operating systems such as Windows still execute execution quanta in 15 milliseconds. pieces, it doesn’t take long to overflow this stack. That would be my first hunch about why everyone is cheating.

PS I just returned from correcting my name, something similar to my actual identity. Then the irony struck that my answer to your question looked at us both in the face in the upper left corner of the browser page! (That is, of course, assuming that I was right that this is often not the case in this business.)

+4
source share

Well, maybe shared memory is not the right design for your problem. However, we would not know, because we do not know what you are trying to achieve in the first place.

-3
source share

All Articles