2013-05-07 25 views
11

私はshmget(2)を介してLinuxシステム上で共有メモリを割り当てるC++アプリケーションを持っています。共有メモリに保存するデータは定期的に増加し、realloc()が通常のメモリを増やす方法と同様に共有メモリのサイズを変更したいと思います。これを行う方法はありますか?私は、IBMのサイトでSHM_SIZEコマンドについて説明している文書を見つけましたが、LinuxおよびBSDのマンページには、Linux固有のセクションでさえも、それがありません。shmctlでLinux共有メモリのサイズを変更できますか?

+0

をインスピレーションとして、http://www.boost.org/doc/libs/1_61_0/doc/html/interprocess/quick_guide.html - 具体的には 'managed_shared_memory'を見てください。これは'共有メモリ内のベクトルです... – Nim

答えて

5

簡単な答え:簡単な方法はありません。

理由はかなり論理的です。共有メモリは、すべてのプロセスの仮想空間に個別に接続されています。各プロセスには独自の仮想アドレス空間があります。各プロセスは、にセグメントを自由にアタッチすることができます(文字通り、アライメントではいくつかの制約があります)任意のアドレス。システムがどのようにして4MiBでエリアを拡張すると、このセグメントのすべての 'ユーザー'が同じ開始アドレスにあるビッグゲットブロックに適合することができると、システムはそれを保証できますか?

しかし、あなたはあきらめるべきではありません!あなたは創造的なことができます。実際のペイロードセグメントに関する情報を格納するヘッダーセグメントを持つアイデアを考え出すことができます。たとえば、ヘッダーセグメントのどこかに記載されているように、idがの既知のものと一致しない場合、ペイロードセグメントを再接続するように、すべてのプロセスをいくつかのルールに従わせることができます。

アドバイス:だけオフセット、私はあなたがこれを知っている疑いがあるが、共有領域内のデータへのポインタを保持することはありません。

私はあなたの愚か者の一部を使用していただければ幸いです。

+0

ありがとう - これは非常に役に立ちます! –

0

あなたの目的のために独自のメモリマネージャを書くことができるようです。概念は非常に単純です:

  1. あなたは共有メモリブロックを持っています。サイズはNバイトです。
  2. 共有メモリの新しいブロックを2*Nサイズで割り当てます。
  3. メモリをあるブロックから別のブロックにコピーします。
  4. 古い共有メモリブロックを解放します。
  5. #2-4をいくつかのルーチンにラップして使用します。

私はそれ以上は何もしません。これはstd::vectorの実装方法です。ほとんどの場合、void *realloc()は、新しいメモリブロックへのポインタを返します(ただし、拡張された古いブロックにはポインタを返しません)。

+0

私はそうすることは、このタイプのメモリの '共有'プロパティが存在しないと考えています。 – GreenScape

関連する問題