11

私が働いているポリシーにより、1.33.1 より新しいバージョンの Boost を使用することができず、4.1.2 より新しいバージョンの GCC を使用することができません。はい、ゴミですが、どうしようもありません。Boost 1.33.1 にはプロセス間ライブラリが含まれていません。

std::mapとはいえ、私のプロジェクトの 1 つでは、std::unordered_map共有メモリに を配置する必要があります。プロセスが単一のプロセス(「サーバー」)によってロードされ、他の多数のプロセスによって読み取られる場合、書き込み/変更は1回だけです。以前に共有メモリ IPC を行ったことがないので、これは私にとってかなり新しい領域です。調べてみましshmget()たが、同じ共有メモリ キーを割り当てに継続的に使用することはできないようです (STL コンテナー アロケーターで必要になると思います)。

共有メモリを使用するNON-BOOST STL アロケーターは他にありますか?

編集:これ以前に行われました。Dobbs 博士は 2003 年に正確にこれを行う方法についての記事を書いており、私はそれを参照として使い始めました。ただし、コード リストは不完全であり、それらへのリンクはメイン サイトにリダイレクトされます。

編集編集: Boost.Interprocess を書き直さない唯一の理由は、関連するコードの量のためです。ネットワーク間のデータ転送も複数日の承認プロセスの対象となるため、最初から書き直すことができるPOSIX共有メモリ専用の比較的短く簡潔なものがあるかどうか疑問に思っていました...

4

2 に答える 2

7

共有メモリを固定アドレス (すべてのプロセスで一貫している) に固定できない場合を除き、ポインターは共有メモリ内で機能しません。そのため、共有メモリがマップされているメモリ領域への連続する (ポインターがない) か、オフセットがある (ポインターではない) 特定のクラスが必要です。

かなり似たような状況で共有メモリを使用しています。1 つのプロセスが一連のデータを計算し、それを共有メモリに配置し、メモリを独自のアドレス空間にマップする可能性があることを他のプロセスに通知します。その後、メモリが変更されることはありません。

私たちがそれを行う方法は、POD構造 (*) (char xxx[N];文字列ストレージの属性を含むもの) を持つことです。実際に文字列を制限できる場合は、ゴールデンです。そして、map読み取り専用ストレージでは効率が悪い=>ソートされた配列の方がパフォーマンスが優れています(メモリの局所性については万歳)。だから私はそれに行くことをお勧めします:

struct Key {
    enum { Size = 318 };
    char value[Size];
};

struct Value {
    enum { Size = 412 };
    enum K { Int, Long, String };
    K kind;
    union { int i; long l; char string[Size]; } value;
};

std::pair<Key, Value>次に、並べ替え ( )の配列を取得し、検索std::sortに使用します。std::lower_bound明らかに、キーの比較演算子を記述する必要があります。

bool operator<(Key const& left, Key const& right) {
    return memcmp(left.value, right.value, Key::Size) < 0;
}

そして、enum + union トリックはブースト バリアントよりも (インターフェイスに関して) 魅力的ではないことに同意します...インターフェイスをより良くするのはあなた次第です。

(*) 実際には、純粋な POD は必要ありません。たとえば、プライベート属性、コンストラクター、コピー コンストラクターを使用してもまったく問題ありません。必要なのは、間接参照 (ポインター) を避けることだけです。

于 2012-09-27T07:45:08.003 に答える
0

簡単な回避策。Boost 1.51 から独自の「libNotBoost v1.0」を作成します。Boost ライブラリでこれが可能になります。これはもはや Boost ではないので、問題ありません。

于 2012-09-27T07:07:10.480 に答える