Note that there are some explanatory texts on larger screens.

plurals
  1. POBoost, Shared Memory and Vectors
    primarykey
    data
    text
    <p>I need to share a stack of strings between processes (possibly more complex objects in the future). I've decided to use boost::interprocess but I can't get it to work. I'm sure it's because I'm not understanding something. I followed their example, but I would really appreciate it if someone with experience with using that library can have a look at my code and tell me what's wrong. The problem is it seems to work but after a few iterations I get all kinds of exceptions both on the reader process and sometimes on the writer process. Here's a simplified version of my implementation:</p> <pre><code>using namespace boost::interprocess; class SharedMemoryWrapper { public: SharedMemoryWrapper(const std::string &amp; 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-&gt;get_segment_manager()); m_stack = m_segment-&gt;construct&lt;StringStack&gt;("MyStack")(*m_stackAllocator); } else { m_segment = new managed_shared_memory(open_only ,name.c_str()); m_stack = m_segment-&gt;find&lt;StringStack&gt;("MyStack").first; } m_mutex = new named_mutex(open_or_create, "named_mutex"); } ~SharedMemoryWrapper() { if (m_server) { named_mutex::remove("named_mutex"); m_segment-&gt;destroy&lt;StringStack&gt;("MyStack"); delete m_stackAllocator; shared_memory_object::remove(m_name.c_str()); } delete m_mutex; delete m_segment; } void push(const std::string &amp; in) { scoped_lock&lt;named_mutex&gt; lock(*m_mutex); boost::interprocess::string inStr(in.c_str()); m_stack-&gt;push_back(inStr); } std::string pop() { scoped_lock&lt;named_mutex&gt; lock(*m_mutex); std::string result = ""; if (m_stack-&gt;size() &gt; 0) { result = std::string(m_stack-&gt;begin()-&gt;c_str()); m_stack-&gt;erase(m_stack-&gt;begin()); } return result; } private: typedef boost::interprocess::allocator&lt;boost::interprocess::string, boost::interprocess::managed_shared_memory::segment_manager&gt; StringStackAllocator; typedef boost::interprocess::vector&lt;boost::interprocess::string, StringStackAllocator&gt; 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; }; </code></pre> <p><em>EDIT</em> Edited to use named_mutex. Original code was using interprocess_mutex which is incorrect, but that wasn't the problem.</p> <p><em>EDIT2</em> I should also note that things work up to a point. The writer process can push several small strings (or one very large string) before the reader breaks. The reader breaks in a way that the line m_stack->begin() does not refer to a valid string. It's garbage. And then further execution throws an exception.</p> <p><em>EDIT3</em> I have modified the class to use boost::interprocess::string rather than std::string. Still the reader fails with invalid memory address. Here is the reader/writer</p> <pre><code>//reader process SharedMemoryWrapper mem("MyMemory", true); std::string myString; int x = 5; do { myString = mem.pop(); if (myString != "") { std::cout &lt;&lt; myString &lt;&lt; std::endl; } } while (1); //while (myString != ""); //writer SharedMemoryWrapper mem("MyMemory", false); for (int i = 0; i &lt; 1000000000; i++) { std::stringstream ss; ss &lt;&lt; i; //causes failure after few thousand iterations //ss &lt;&lt; "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" &lt;&lt; i; //causes immediate failure mem.push(ss.str()); } return 0; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload