1

I m having problem with sharing vectors between processes. I can share the vector and i can even get the size of the vector from the different process, but when i use at function, program just crash.

    struct B
   {
      std::vector<int> vec;
   };

    int main(int cArgs, char* ppszArgs[])
   {
       if (cArgs == 1) {  //Parent process
          //Remove shared memory on construction and destruction
       struct shm_remove
        {
        shm_remove() { shared_memory_object::remove("MySharedMemory"); }
        ~shm_remove() { shared_memory_object::remove("MySharedMemory"); }
       } remover;

    //Create a shared memory object.
    shared_memory_object shm(create_only, "MySharedMemory", read_write);

    //Set size
    shm.truncate(1000);

    //Map the whole shared memory in this process
    mapped_region region(shm, read_write);

    //Write all the memory to 1
    B* test = new B();


    CopyMemory(region.get_address(), test, sizeof(B));


    parentProcess(); -> this method just starts the child process

    int index = 1;
    while (true)
    {
        if(index < 2)
        {
            ((B*)region.get_address())->vec.push_back(index);
        }
        ++index;
    }

}
else
{
    //Open already created shared memory object.
    shared_memory_object shm(open_only, "MySharedMemory", read_only);

    //Map the whole shared memory in this process
    mapped_region region(shm, read_only);

    //Check that memory was initialized to 1
    HANDLE mem = region.get_address();


    while(true)
    {
        std::cout << ((B*)mem)->vec.at(0) << std::endl; -> if for example i put 
        lista.size(), then i will get the number of items in vector.
    }

}

}

My question is it even possible to access vector elements from child process ?

Filip Cacic
  • 77
  • 1
  • 7
  • Out of the box C++ does not support this. – Eljay Apr 12 '20 at 21:59
  • `CopyMemory(region.get_address(), test, sizeof(B));` -- This could never work. The `sizeof(B)` will never change, whether you had no elements, or 100 elements, (or a million elements) in the vector, since `sizeof(B)` is a compile-time constant – PaulMcKenzie Apr 12 '20 at 22:05
  • You need inter process communication. You can use sockets, pipes, or, in Windows, file mapping. – Michael Chourdakis Apr 12 '20 at 22:23

1 Answers1

2

Yes, you absolutely can do this. You need to use the boost interprocess libraries. You need (1) a mutex to arbitrate access to the vector and (2) you need to be able to allocate the vector elements in shared memory. You should be able to do this in one segment of shared memory. However I couldn't get it working on short notice. Here is the solution using two shared memory segments, one for the mutex and one for the vector.

#include <iostream>
#include <string>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/chrono.hpp>
#include <boost/thread/thread.hpp> 

using namespace boost::interprocess;

typedef allocator<int, managed_shared_memory::segment_manager>
ShmemAllocator;

typedef std::vector<int, ShmemAllocator> MyVector;


struct B
{
    boost::interprocess::interprocess_mutex mutex;
};

int main(int cArgs, char* ppszArgs[])
{

    if (cArgs== 1) {  //Parent process
        std::cout << "In parent" << std::endl;

       //Remove shared memory on construction and destruction
        struct shm_remove
        {
            shm_remove() { shared_memory_object::remove("MutexMemory"); }
            ~shm_remove() { shared_memory_object::remove("MutexMemory"); }
        } remover;
        shared_memory_object::remove("VectorMemory");
        managed_shared_memory segment
        (create_only
            , "VectorMemory" //segment name
            , 65536);          //segment size in bytes


        const ShmemAllocator alloc_inst(segment.get_segment_manager());

        shared_memory_object shm(create_only, "MutexMemory", read_write);


        MyVector* myvector =
            segment.construct<MyVector>("MyVector") //object name
            (alloc_inst);//first ctor parameter

        shm.truncate(1000);

        mapped_region region(shm, read_write);
        void* addr = region.get_address();
        B* test = new (addr) B();



        //        parentProcess(); -> this method just starts the child process

        int index = 1;
        while (true)
        {
            if (index < 10000)
            {
                scoped_lock<interprocess_mutex> lock(test->mutex);
                myvector->push_back(index);
            }
            Sleep(1000);
            ++index;
        }

    }
    else
    {
        std::cout << "In child" << std::endl;
        //Open already created shared memory object.
        shared_memory_object shm(open_only, "MutexMemory", read_write);

        //Map the whole shared memory in this process
        mapped_region region(shm, read_write);
        B* mem = (B*)region.get_address();
        managed_shared_memory segment
        (open_only
            , "VectorMemory");  //segment name

        MyVector* myvector = segment.find<MyVector>("MyVector").first;

        while (true)
        {
            if(1)
            {
                scoped_lock<interprocess_mutex> lock(mem->mutex);
                std::cout << (myvector->size() == 0 ? -1 : (*myvector)[myvector->size() - 1]) << std::endl;
            }
            Sleep(1000);

        }

    }
}
AQuirky
  • 4,691
  • 2
  • 32
  • 51