したがって、スレッドで機能する単純なクラスを作成しました。任意のクラスの 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(¤tClassName::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 があり、あるプロセスから関数のポインターを共有し、ブローカー アプリを使用してそのポインターを別のアプリに渡して、最後のプロセス/アプリからのパラメーターで呼び出すことができるとしたらどうでしょうか?
実際には、編集可能なテキスト フィールドが実行されていないアプリと、編集可能なテキスト フィールドが実行されているアプリがあるとします。そして、編集可能なTFから編集不可能なTFへの入力を接続できるアプリ№3がありました。
Boost.Interprocessで可能で、そのようなことを行う方法はありますか?
私はC ++にかなり慣れていませんが、関連する悪い情報を見つけたと思います:
参照禁止
参照は、ポインターと同じ問題を抱えています (主に参照がポインターとして実装されているため)。ただし、現在 C++ で完全に機能するスマート参照を作成することはできません (たとえば、operator .() はオーバーロードできません)。このため、ユーザーがオブジェクトを共有メモリに配置したい場合、オブジェクトはメンバーとして (スマートであるかどうかに関係なく) 参照を持つことはできません。
参照は、メモリ セグメントを共有するすべてのプロセスで、マップされた領域が同じベース アドレスにマップされている場合にのみ機能します。ポインターと同様に、マップされた領域に配置された参照は、そのマップされた領域のオブジェクトのみを指す必要があります。
仮想性の禁止
仮想テーブル ポインタと仮想テーブルは、オブジェクトを構築するプロセスのアドレス空間にあるため、仮想関数または仮想基底クラスでクラスを配置すると、共有メモリに配置された仮想ポインタは他のプロセスに対して無効になり、彼らはクラッシュします。
各プロセスには異なる仮想テーブル ポインタが必要であり、そのポインタを含むオブジェクトは多くのプロセスで共有されるため、この問題を解決するのは非常に困難です。マップされた領域をすべてのプロセスで同じアドレスにマップしたとしても、仮想テーブルはすべてのプロセスで異なるアドレスになる可能性があります。プロセス間で共有されるオブジェクトの仮想関数を有効にするには、コンパイラの大幅な変更が必要であり、仮想関数のパフォーマンスが低下します。そのため、Boost.Interprocess には、プロセス間で共有されるマップされた領域で仮想関数と仮想継承をサポートする計画はありません。
静的クラス メンバーに注意する
クラスの静的メンバーは、クラスのすべてのインスタンスによって共有されるグローバル オブジェクトです。このため、静的メンバーはプロセス内のグローバル変数として実装されます。
静的メンバーでクラスを構築する場合、各プロセスには静的メンバーの独自のコピーがあるため、あるプロセスで静的メンバーを更新しても、別のプロセスの静的メンバーの値は変更されません。したがって、これらのクラスには注意してください。静的メンバーは、プロセスの開始時に初期化される単なる定数変数である場合は危険ではありませんが、まったく変更されず (たとえば、列挙型のように使用される場合)、その値はすべて同じです。
しかし、1 つの同じライブラリを使用してすべてのアプリを作成しています。最高のパフォーマンスが必要な場合はスレッドを使用しますが、プロセス間通信が必要になる場合があります。では、どうすればよいでしょうか - 必要な機能をエミュレートするメカニズムを作成するにはどうすればよいでしょうか?