Доступ к векторному элементу общего объекта с помощью boost interprocess - PullRequest
1 голос
/ 27 октября 2010

Я пытаюсь понять, как работает библиотека interprocess boost.У меня есть класс Equipment, который содержит целочисленные значения в векторном контейнере.

В родительском родительском процессе;Я сконструировал объект Equipment в MySegmentObject сегменте, и в конструкторе этого объекта я создал вектор в MySegmentVector сегмент.

Используя дочерний процесс;Я хочу получить доступ к созданному объекту и получить размер вектора.Я могу получить доступ к объекту с помощью метода segment->find, но когда я вызываю метод getSize() из объекта, к которому получен доступ, происходит сбой!

Что я делаю не так, возможно, мне не хватает концепции общей памяти.

Я протестировал код в Visual Studio 2010 и ускорился 1.43.0 lib

Equipments.h

#pragma once
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>

using namespace boost::interprocess;

typedef boost::interprocess::allocator<int, managed_shared_memory::segment_manager>     ShmemAllocator; 
typedef boost::container::vector<int, ShmemAllocator> EqVector;

class Equipments { 
public:     
    Equipments(void);   
    ~Equipments(void);  
    void addEquipment(int n);   
    int getSize();  
    int getElement(int n);

private:
    const ShmemAllocator *alloc_inst;
    <offset_ptr>EqVector eqVector;
    managed_shared_memory *segment;
};

Equipments.cpp

#include "StdAfx.h"
#include "Equipments.h"
#include <iostream>

Equipments::Equipments(void)
{   
    shared_memory_object::remove("mySegmentVector"); 
    segment = new managed_shared_memory(create_only, "mySegmentObjectVector", 65536);
    alloc_inst = new ShmemAllocator(segment->get_segment_manager());
    eqVector = segment->construct<EqVector>("myVector")(*alloc_inst);
}


Equipments::~Equipments(void)
{
}

void Equipments::addEquipment(int n)
{
    eqVector->push_back(n);
}

int Equipments::getSize()
{
    return eqVector->size();
}

int Equipments::getElement(int n)
{
    return eqVector->at(n);
}

Main.cpp

#include "stdafx.h"
#include "Equipments.h"
#include <iostream>
#include <string>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>

using namespace boost::interprocess;

int main(int argc, char *argv[]) 
{
    if (argc == 1) 
    {
        std::cout << "parent process" << std::endl;
        shared_memory_object::remove("mySegmentObject"); 
        managed_shared_memory segment(create_only, "mySegmentObject", 65536);
        Equipments *eqPtr = segment.construct<Equipments>("EQ")();

        eqPtr->addEquipment(19);
        eqPtr->addEquipment(12);

        //Launch child process
        std::string s(argv[0]); s += " child ";
        if(0 != std::system(s.c_str()))
            return 1;        //Launch child process
    }
    else 
    {
        std::cout << "child process" << std::endl;
        managed_shared_memory *segment = new managed_shared_memory(open_only, "mySegmentObject");
        std::pair<Equipments*, std::size_t> p = segment->find<Equipments>("EQ");

        if (p.first) 
        {
            std::cout << "EQ found" << std::endl;       
       std::cout << p.first->getSize() << std::endl;       
        }
        else 
        {
            std::cout << "EQ not found" << std::endl;
        }
    }
}

1 Ответ

6 голосов
/ 27 октября 2010

Проблема в том, что вы используете обычный указатель для хранения вашего EqVector.Когда вы отображаете сегмент общей памяти, он может отображаться в любое место в адресном пространстве процесса.Это означает, что место, где eqVector хранится в памяти, в первом процессе отличается от «пространства памяти, чем во втором процессе».Вам нужно использовать boost :: offset_ptr, который хранит адреса как смещения от начала сегментов разделяемой памяти, см. Здесь: http://www.boost.org/doc/libs/1_35_0/doc/html/interprocess/offset_ptr.html

...