1

I would like to place a struct in a shared memory using Boost.Interprocess. This struct will be shared between two processes as a main exchange zone for serialized data. I am currently searching for the best solution in term of simplicity.

namespace bi = boost::interprocess;

typedef bi::allocator<SimpleData, bi::managed_shared_memory::segment_manager>   ShmemSimpleDataAllocator;
typedef bi::vector<SimpleData, ShmemSimpleDataAllocator>                        SimpleDataVector;

struct SimpleData
{
    SimpleData() {}
    SimpleData(char* ptr)
        :data(ptr)
    {}

    /** Offset pointer to the data */
    bi::offset_ptr<char> data;
};

// Main shared structure
struct SharedMainStruct // EDITED, thanks Sehe
{
    SharedMainStruct(ShmemSimpleDataAllocator simple_allocator)
     :m_inputs(simple_allocator),
      m_outputs(simple_allocator)
    {}

    // Inputs, outputs and properties
    SimpleDataVector    m_inputs;
    SimpleDataVector    m_outputs;

    bi::interprocess_mutex     m_mutex;
    bi::interprocess_condition m_cond;
};

// Main code here
// Create managed shared memory
my_sho= new bi::managed_shared_memory (bi::create_only, "test_SO", 1000000);

// Build main structure in shared memory
ShmemSimpleDataAllocator data_allocator(my_sho->get_segment_manager());
m_main_struct = my_sho->construct<SharedMainStruct>("main")(data_allocator); // (1)

The idea is to place this SharedMainStruct in shared memory so that it is accessible for both processes. Is this code line (1) correct ? I would guess that I miss some runtime code like in the documentation right ? Like :

//Initialize shared memory STL-compatible allocator
const ShmemSimpleDataAllocatoralloc_inst (segment.get_segment_manager());

//Construct a vector named "MyVector" in shared memory with argument alloc_inst
SimpleDataVector* myvector = segment.construct<SimpleDataVector>("SimpleDataVector")(alloc_inst);

-- UPDATE --

Yes, Vectors can be stored as member variables. We should provide allocators as parameters of the constructor...

poukill
  • 540
  • 8
  • 18

1 Answers1

1

The essence:

Classes are laid out contiguously in memory, so you cannot literally store some parts of it selectively in shared memory.

For the same reason, storing offset_ptr outside shared-memory is useless, and you can simply replace it by a raw pointer.

Further brainstorming

The previous two sentences should be enough to clear up any confusion.

You /can/ of course store the MainStruct in shared memory. This could help iff all data in the MainStruct can be shared.

If you need so share just that part of MainStruct, it seems obvious to make that explicit:

// Inputs, outputs and properties
struct SharedBuffers {
     template <typename Alloc> 
     SharedBuffers(Alloc alloc = {}) : m_inputs(alloc), m_outputs(alloc) {}

     Shared::Vector<SimpleData> m_inputs;
     Shared::Vector<SimpleData> m_outputs;
};

SharedBuffers* m_buffers; // bip::offset_ptr<> is overkill outside shared memory

Mild suggestion to replace the 'raw' offset_ptr` with a shared vector of char instead.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Yes I would like to put all the `MainStruct` in shared memory. I specified in my code : `m_main_struct = m_sho->construct("main")();`. – poukill Jul 25 '17 at 13:21
  • Then why are you concerned about the vectors? Just make sure they use shared memory allocators, and be happy. – sehe Jul 25 '17 at 15:36
  • Well, I think I'm not too far from being happy. I just try to find the best solution to my problem. I rewrote partially my question. From your code, I have the impression that I can build my vector members through the initialization list by providing the allocator as an argument. Is that correct ? – poukill Jul 25 '17 at 16:37
  • You were right. I tried this ```ShmemSimpleDataAllocator data_allocator(m_sho->get_segment_manager()); m_main_struct = m_sho->construct("main")(data_allocator);``` and it seems to work well. Thanks a lot, that part of the documentation was not clear to me. – poukill Jul 25 '17 at 16:51
  • Indeed. I have quite a lot of answers on Boost Inteprocess, including scoped_allocator_adaptor that may make your life easier. Feel free to browse through them – sehe Jul 25 '17 at 18:29
  • Yes, I did find them before posting, but now it is clearer to me. Thanks again Sehe. :) – poukill Jul 25 '17 at 18:40