12

boost::interprocessを介して共有メモリの静的チャンクを作成するときに、どれだけのメモリを割り当てる必要があるかについて、決定的な答え(実際に存在する場合)を探していますmanaged_shared_memory公式の例でさえ、任意に大きなメモリのチャンクを割り当てているようです。

次の構造を検討してください。

// Example: simple struct with two 4-byte fields
struct Point2D {
  int x, y;
};

私の最初の反応は、必要なサイズは 8 バイト、つまりsizeof(Point2D). オブジェクトを構築しようとすると、これは惨めに失敗し、実行時にセグメンテーション違反が発生します。

// BAD: 8 bytes is nowhere near enough memory allocated.
managed_shared_memory segment(create_only, "My shared memory", sizeof(Point2D));

seg-fault の原因となっている読み取り/書き込み操作は何ですか? スタック操作?segment.construct()?内の一時的な割り当て 共有メモリを割り当てる際に必要なオーバーヘッドはどれくらいですか?

試行錯誤の結果、上記の構造ではサイズを 4 倍にするとうまくいくことがわかりましたが、 にフィールドを追加し始めるとうまくいきませんstruct。だから、それは悪いハックのにおいがします。

現代の PC では「メモリは安い」と主張する人もいるかもしれませんが、私はこの考え方に同意せず、必要以上に割り当てることを避けることができれば嫌いです。昨日、Boost のドキュメントを調べてみましたが、推奨事項が見つかりませんでした。今日は何か新しいことを学びましょう!

4

2 に答える 2

9

ドキュメントのこの段落から:

メモリ アルゴリズムは、共有メモリ/メモリ マップ ファイル セグメントの最初のバイトに配置されるオブジェクトです。

メモリ セグメントのレイアウト:

 ____________ __________ ____________________________________________  
|            |          |                                            | 
|   memory   | reserved |  The memory algorithm will return portions | 
| algorithm  |          |  of the rest of the segment.               | 
|____________|__________|____________________________________________| 

ライブラリには、セグメントの先頭に余分なメモリ オーバーヘッドがあるため、要求されたサイズの数バイトが占有されます。この投稿およびこの投稿によると、この正確な追加バイト数は特定できません。

割り当て/割り当て解除パターンに応じて実行時に変化するメモリ割り当て予約と断片化の問題があるため、計算できません。また、共有メモリは OS によってページ単位で割り当てられるため (Linux では 4K、Windows では 64K)、割り当ては実際にはページに丸められて割り当てられます。

    managed_shared_memory segment(create_only, "name", 20);

次のように同じメモリを浪費します。

    managed_shared_memory segment(create_only, "name", 4096);
于 2010-11-12T16:54:07.863 に答える
3

OSのメモリページサイズを使用するようなものが機能します。私の場合、これは動作します..

off_t size = sizeof(class1) + (sizeof(class2) * 3);
// round up to the OS page size.
long page_size = sysconf(_SC_PAGE_SIZE);
size = ((size / page_size) + (size % page_size ? 1 : 0)) * page_size;

boost::managed_shared_memory を使用すると、結果のスペースにオブジェクトを構築できます。何かのようなもの....

shared_memory_object::remove(m_name.c_str());
m_shared.reset(new managed_shared_memory(create_only, "myspace", size));
m_class1 = m_shared->construct<class1>("class1")();
m_class2 = m_shared->construct<class2>("class2")[3]();
于 2011-01-12T01:33:23.897 に答える