web-dev-qa-db-ja.com

MMAPについて

MMAPに関するドキュメントを調べていたところ here を使用して実装しました this

その実装について、いくつか疑問があります。

  1. MMAPはファイルのマッピングを提供し、物理メモリ内のその場所のポインターを返しますか、それともマッピングテーブルのアドレスを返しますか?そして、そのファイルにもスペースを割り当ててロックしますか?

  2. ファイルがメモリ内のその場所に格納されたら、munmapが呼び出されるまでファイルはそのまま残りますか?

  3. ファイルはメモリに移動されますか、それともリダイレクトとして機能する単なるマッピングテーブルであり、ファイルは実際には仮想メモリ(ディスク)にありますか?

  4. メモリに移動したと仮定すると、他のプロセスがアドレスを持っている場合、そのスペースにアクセスしてデータを読み取ることができますか?

9
john

順番に答える:

  1. virtualメモリ内の場所へのポインタを返し、仮想メモリアドレス空間が割り当てられますが、明示的にロックしない限り、ファイルはロックされません(メモリのロックは、ファイル内の領域をロックするのと同じです)。 mmap()の効率的な実装は、ページングと仮想メモリのため、実際には実際的な観点からのみ可能です(そうでない場合、領域全体をメモリに読み込む必要がありますbefore呼び出しが完了します)。
  2. 正確ではありませんが、これは次の回答と結びついているので、ここで説明します。
  3. やや。ほとんどの場合、実際に起こっていることは、mmap()がページキャッシュ内のそのファイルのデータへのコピーオンライトアクセスを提供していることです。その結果、データの有効期間に対する通常のキャッシュ制限が適用されます(システムにスペースが必要な場合、ページがキャッシュから削除(またはダーティになっている場合はディスクにフラッシュ)され、再度フォールトする必要があります)。
  4. いいえ、仮想メモリの仕組みのためです。各プロセスには独自の仮想アドレス空間があり、独自の仮想マッピングがあります。データを通信したいすべてのプログラムは、同じファイル(または共有メモリセグメント)でmmap()を呼び出す必要があり、それらはすべてMAP_SHAREDフラグを使用する必要があります。

Mmap()はファイルに対して機能するだけでなく、次のような他のことも実行できることに注意してください。

  • デバイスメモリを直接マッピングする(十分な権限がある場合)。これは、実際には多くの組み込みシステムで使用され、新しいハードウェア用のカーネルモードドライバーを作成する必要がありません。
  • 共有メモリセグメントをマップします。
  • 巨大なページを明示的にマップします。
  • Madvise(2)を呼び出すことができるメモリを割り当てます(これにより、fork(2)で子プロセスにデータがコピーされないようにしたり、KSM(Linuxのメモリ重複排除機能)のデータにマークを付けたりすることができます)。
12