Boost.Interprocess: как вызвать и отправить данные в функцию из класса, который находится в другом процессе? - PullRequest
1 голос
/ 02 марта 2011

Итак, я создал простой класс, который работает с потоками - вы можете добавить любую функцию void любого класса в список подписанных функций класса, который унаследован от представленного моего класса:

#include <iostream>
#include <vector>

#include <boost/thread.hpp>

// parts of c++0x std
#include <boost/bind.hpp> 
#include <boost/function.hpp>

#ifndef _CoreEvents_h_
#define _CoreEvents_h_

using namespace std ;
template <typename DataType >
class CoreEvents{

        typedef boost::function<void(DataType)>   Function;
        typedef std::vector<Function>      FunctionSequence;
        typedef typename FunctionSequence::iterator FunctionIterator; 

public:
        DataType* dataElement;
        FunctionSequence funcs;
        boost::thread_group tg;

        CoreEvents()
        {
                dataElement = new DataType();
        }
        // Function for adding subscribers functions
        // use something like std::bind(&currentClassName::FunctionToAdd, this, std::placeholders::_1) to add function to vector
        void Add(Function f)
        {
                funcs.push_back(f);
        }

        // Cast data to subscribers and clean up given pointer
        //ToDo: One  will be solved when pool of pre-initialized objects will be developed 
        virtual void Cast(){
                for (FunctionIterator it(funcs.begin()); it != funcs.end(); ++it){
                        DataType dataCopy = *dataElement;
                        tg.create_thread(boost::bind(*it, dataCopy));
                }
        }  
};

Все, что вам нужно, чтобы подписаться на это:

someClass->Add(boost::bind(&someOtherClass::someVoidFunction, this, _1)); 

Это просто, когда мы имеем дело с потоками - мы всегда можем вызвать, например, create_thread и получить все, что нам нужно, в другом потоке приложения.

Но что, если у нас есть app1, app2 и app3, и вы хотите поделиться указателем на функцию из одного процесса и, используя приложение брокера, передать этот указатель на другое приложение, чтобы его можно было вызывать с параметрами из последнего процесса / приложения?

В реальной жизни это выглядело бы так, как если бы у нас было приложение с не редактируемым текстовым полем и приложение с редактируемым текстовым полем. и у нас было приложение №3, которое могло подключить вход от редактируемого TF к не редактируемому TF.

Возможно ли это с Boost.Interprocess и как это сделать?

Я довольно новичок в C ++, но думаю, что нашел плохую информацию, связанную :

Ссылки запрещены

Ссылки страдают от того же проблема как указатели (в основном потому, что они реализованы как указатели). Тем не менее, невозможно создать полностью работоспособный умный справочник в настоящее время в C ++ (например, оператор. () не может быть перегружен). Из-за этого, если пользователь хочет поместить объект в общую память, объект не может иметь (умный или нет) ссылка как участник.

Ссылки будут работать только если сопоставленный регион отображается в том же базовый адрес во всех процессах совместного использования сегмент памяти. Как указатели, ссылка размещена в отображаемой области следует указывать только на объект этого сопоставленный регион.

Виртуальность запрещена

Указатель виртуальной таблицы и виртуальные таблицы находятся в адресном пространстве процесса, который создает объект, поэтому если мы поместим класс с виртуальная функция или виртуальная база класс, виртуальный указатель, помещенный в общая память будет недействительной для другие процессы, и они будут падать.

Эта проблема очень сложна решить, так как каждый процесс нуждается в другой указатель виртуальной таблицы и объект, который содержит этот указатель распределяется между многими процессами. Четное если мы сопоставим отображенную область в один и тот же адрес в каждом процессе, виртуальная таблица может быть в другом адрес в каждом процессе. Включить виртуальные функции для общих объектов между процессами, глубокий компилятор изменения нужны и виртуальные функции пострадают производительность удар. Вот почему Boost.Interprocess не имеет никакого плана поддержки виртуальная функция и виртуальная общее наследование в отображенных регионах между процессами.

Будьте осторожны со статическими учениками

Статические члены классов являются глобальными объекты, общие для всех экземпляров учебный класс. Из-за этого статические члены реализованы как глобальные переменные в процессы.

При создании класса со статическим члены, каждый процесс имеет свою копию статического члена, поэтому обновление статический член в одном процессе не изменить значение статического члена другой процесс. Так что будьте осторожны с этими классами. Статические члены не опасно, если они просто постоянные переменные инициализируются, когда процесс начинается, но они этого не делают изменить вообще (например, при использовании как перечисления) и их значение одинаково для всех.

Но я создаю все свои приложения, используя одну и ту же библиотеку. и когда мне нужна лучшая производительность, я буду использовать многопоточность, но бывает, что мне нужно межпроцессное взаимодействие. Так что мне делать - как создать механизм для эмуляции столь необходимой функциональности?

1 Ответ

2 голосов
/ 02 марта 2011

Извините, этот вопрос немного сложен для понимания, но я постараюсь ответить.

Совместное использование указателей функций между процессами - это то, что вы должны почти никогда делать. Это очень опасно. Обмен непримитивными данными также не одобряется, но в некоторых случаях это нормально.

Как правило, вы должны использовать что-то вроде обмена сообщениями для этого. Вы можете использовать Boost.Interprocess для обмена параметрами.

...