2012-10-29 4 views
7
  • shm_open()
  • mmap()
  • ftruncate()は、この時点ではfork()によって生成されたすべてのプロセスを持っていることを確認する

ある同じアドレスの共有セグメントしかし、私はRAMを常にビジー状態に保ちたいとは思っていませんが、動的にサイズを変更します(サイズ0〜ビッグサイズlength)。ben mmapされた共有メモリオブジェクトをftruncateするのは安全ですか?意志で事前に定義された大きな<code>length</code></li> <li><code>fork()</code>(数回)と

これは動作しますか? UBはありますか?

答えて

8

いいえ、それは問題ありません。いつでも基になるファイルを切り捨てることができますが、ファイルの境界を超えてメモリにアクセスすると、SIGBUSが返されることがあります。したがって、ファイルの現在の長さを超えてメモリに触れないように(またはSIGBUSを捕まえてそれに対処しないように)注意する必要があります。 man 2 mmapから

マッピングされた領域の

使用し、これらの信号をもたらすことができる :

SIGBUSを超えて(例えば、ファイルを するために対応していないバッファの部分へのアクセスを試み別のプロセスがファイルを切り捨てた場合を含む を含むファイルの終わり)。

+0

これは私が前提にしていますが、 'munmap'トリガーが' SIGBUS'を引き起こす恐れのあるページに書き込むことができますか? –

+0

これは私の質問に答えるので、これを受け入れたものとしてマークします。しかし、Damonの方法は、管理が容易です(私は 'mmap'ed範囲の真中でページをアンロードできます)。 –

+0

@nneonneo私はこれがかなり正しいとは思わない。私はマッピングを更新するために 'ftruncate'の後に' mremap'をする必要があると思います。それでも、 'mremap'が' ENOMEM'で失敗するのを防ぐために、もともと大きなサイズを割り当てるべきです。 – jleahy

1

サイズを変更しないでください。

私は忙しいカーネルが仮想メモリであなたのために何をするかだすべての時間

をRAMを維持する必要はありません。 mlock()またはMAP_LOCKEDを使用しない限り、必要に応じてページングされます。

+0

、RAM、スワップマップされた領域の途中で(カーネルに強制的にコミットさせて)何かを使うかもしれませんが、残りのランタイムではそれを忘れることができます。だから私は、私がアドレス空間のその部分をもう使用していないと明示的に伝える方法が必要だと思う。 –

+0

'madvise()'を使うことができますが、動作には何の保証もありません。 –

+0

私は 'MADV_REMOVE'を使うと思います。しかし、もし私がそのスペースを取り戻す必要があれば、どうすればいいですか? –

1

実際に使用しない限り、大量のマッピングを作成しても、RAMをビジー状態にすることはありません。あなたは、あなたがそれを使用してを行われた後忙しいRAMを維持を心配している場合

madvise(MADV_DONTNEED)を呼び出す - これはページを削除し、再度アクセスした場合、ゼロプールから新しいページをあなたに戻って得られます。

+0

'MADV_DONTNEED'とマークされた範囲に書き込む前に、実行する必要がある操作はありません。 –

+0

ゼロ補充の振る舞いは、バッキングストアがそれらのページをもはや持っていない場合にのみ起こることに注意してください(疑問に思うかもしれませんが、一部のデータは 'ftruncate'によって破棄されたかもしれません)。 –

+0

@LorenzoPistone:何もする必要はありません。 'MADV_DONTNEED'はページを破棄し、必要に応じてディスクからページをリロードします(ファイルがバックアップされている場合)。 POSIXではセマンティクスが変更されていないと主張しているので、後者は少なくとも私の意見では実際は「正しくない」振る舞いであることに注意してください。しかし、あなたが欲しいのはそれだけです。 – Damon

関連する問題

 関連する問題