2

I found this code online (http://prakharprakhar.blogspot.co.uk/2009/12/boost-shared-memory-vector.html), detailing how to share a vector via Boost Interprocess:

Writing to vector in shared memory

using namespace boost::interprocess;

using ShmemAllocator = allocator<int, managed_shared_memory::segment_manager>;
using MyVector = vector<int, ShmemAllocator>

int main()
{
    shared_memory_object::remove("MySharedMemory");

    managed_shared_memory segment(create_only, "MySharedMemory", 65536);

    const ShmemAllocator alloc_inst(segment.get_segment_manager());

    MyVector* myVector = segment.construct<MyVector>("MyVector")(alloc_inst);

    for(int i = 0; i < 100; ++i)
    {
        myVector->push_back(i);
    }
}

Reading from vector in shared memory

int main()
{
    using namespace boost::interprocess;

    using ShmemAllocator = allocator<int, managed_shared_memory::segment_manager>
    using MyVector = vector<int, ShmemAllocator>;

    managed_shared_memory segment(open_only, "MySharedMemory");
    MyVector* myVector = segment.find<MyVector>("MyVector").first;

    std::cout << "Size of shared vector: " << myVector->size() << std::endl;

    MyVector::iterator iter = myVector->begin();
    while(iter++ != myVector->end())
    {
        std::cout << "nvalue = " << *iter << std::endl;
    }

    //segment.destroy<MyVector>("MyVector");
}

However, I would like to synchronise my two processes/threads. I require a mutex to prevent both accessing at the same time and a condition variable to notify the reader that there is data.

From reading here:

https://www.boost.org/doc/libs/1_57_0/doc/html/interprocess/synchronization_mechanisms.html

I see that the typical design is to place the mutex and condition variable within the object being shared across memory. I therefore proceeded to create a struct:

struct MySharedData
{
    MyVector vec;
    interprocess_mutex      mutex;
    interprocess_condition  cond_empty;
}

However, the Boost documentation examples don't require a shared memory allocator, so I am unsure if I can simply place MyVector within the struct.

How would I integrate having the custom vector allocator with a "wrapper" struct, to contain the mutex and condition variable?

user997112
  • 29,025
  • 43
  • 182
  • 361

1 Answers1

1

I therefore proceeded to create a struct:

struct MySharedData
{
    MyVector vec;
    interprocess_mutex      mutex;
    interprocess_condition  cond_empty;
}

That looks sane and clean. Why would there be a problem? Just add a constructor to initialize the vector's allocator. This could work:

MySharedData::MySharedData(managed_shared_memory::segment_manager* sm) 
   : vec(sm) 
{}
sehe
  • 374,641
  • 47
  • 450
  • 633
  • and simply call segment.find("MyVector").first from the constructor body? – user997112 Apr 17 '18 at 14:51
  • No. Simply do `segment.find_or_construct("MySharedData")(segment.get_segment_manager());` :) – sehe Apr 17 '18 at 15:06
  • Why find_or_construct() here, but in my example they use find()? Don't both scenarios require construction of a vector? – user997112 Apr 18 '18 at 09:46
  • It's just an example. Use what you need. If you wanted to construct a vector, you use `construct`. If you want to find a constructed vector, use `find`. etc. :) The point is that you create the whole class, so that you don't have fiddle with separate objects in the managed segment – sehe Apr 18 '18 at 09:47
  • Sorry, my mistake. I was looking at the "read" code to relate to your "write" code. – user997112 Apr 18 '18 at 10:57