Как использовать векторы совместного использования в нескольких процессах в C ++ - PullRequest
0 голосов
/ 13 апреля 2020

У меня проблема с разделением векторов между процессами. Я могу поделиться вектором и даже получить размер вектора из другого процесса, но когда я использую функцию, программа просто делает cra sh.

    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.
    }

}

}

Мой вопрос, возможно ли получить доступ к элементам вектора из дочернего процесса?

1 Ответ

1 голос
/ 13 апреля 2020

Да, вы абсолютно можете это сделать. Вам необходимо использовать межпроцессные библиотеки boost. Вам нужен (1) мьютекс для арбитража доступа к вектору и (2) вы должны иметь возможность размещать элементы вектора в разделяемой памяти. Вы должны быть в состоянии сделать это в одном сегменте разделяемой памяти. Однако я не мог заставить его работать в короткие сроки. Вот решение, использующее два сегмента общей памяти, один для мьютекса и один для вектора.

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

        }

    }
}
...