Boost logo

Boost Users :

Subject: [Boost-users] Mutex synchronised wrapper class for boost::interprocess shared memory vector of strings
From: Riskybiz (riskybizLive_at_[hidden])
Date: 2013-06-21 12:13:31


I'm trying to create a wrapper class to control a managed shared memory
segment using Boost::Interprocess. I'm having trouble reading data from the
shared memory vector of strings...

 

When the vector is instantiated in the managed shared segment I place in the
first vector element a test string; "testing testing 1 2 3". Immediately
after placing it there and in the scope of the same code block I can access
the vector element and print out the string using std::cout.

 

However when I try to read the vector element using the read() function the
test program crashes. The problem is with the line:

 

std::string stdStr = sharedSegmentVector->at(index).c_str();

 

Question is how to fix this? I'm confused because at instantiation time
this same code will access the shared memory vector; later on in the read()
function it will not.

 

I've as yet been unable to test the write() function; because I can't yet
read() the vector!

 

Any help to get this working is much appreciated,

 

With thanks,

 

Riskybiz

 

 

Class Definition:

 

#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>

 

#include <iostream>

#include <stdexcept>

 

 

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);

std::string outStr = sharedSegmentVector->at(0).c_str();

std::cout << "Shared Memory Vector Instantiated: Index 0 Data is: " <<
outStr << std::endl;

}

        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)

    {

     

try

{

CharAllocator charallocator(m_segment->get_segment_manager());

     scoped_lock<named_mutex> lock(*m_mutex);

MyShmString shmStr(in.c_str(), charallocator);

     sharedSegmentVector->push_back(shmStr);

}

catch(...)

{

std::cout << "Error in SharedMemoryWrapper::write(): unknown error" <<
std::endl;

}

    }

    

//Reader

std::string read(int index)

{

try

{

scoped_lock<named_mutex> lock(*m_mutex);

std::cout << "Shared Memory Vector Entered Read(), Passed Index: " << index
<< std::endl;

std::string stdStr = sharedSegmentVector->at(index).c_str();

std::cout << "Shared Memory Vector Read At: Index" << index << "Data is: "
<< stdStr << std::endl;

return stdStr;

}

catch(std::range_error err)

{

std::cout << "Error in SharedMemoryWrapper::read(): range_error" <<
std::endl;

}

catch(...)

{

std::cout << "Error in SharedMemoryWrapper::read(): unknown error " <<
std::endl;

}

return "ERROR IN SharedMemoryWrapper::read()";

}

 

 

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

 

Test Programme:

 

#include "stdafx.h"

#include "SharedMemoryWrapper.h"

#include <iostream>

#include <string>

 

int main(int argc, char *argv[])

{

SharedMemoryWrapper *smw = new SharedMemoryWrapper("SharedMemory1", true);

 

std::string outStr = smw->read(0);

 

std::cout << outStr << 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