ファイルをメモリにマップするときは、システム コールが必要です。ファイルへの後続のアクセスにはシステム コールが必要ですか、それともプロセスの仮想メモリ ページはメモリ内の実際のページ キャッシュにマップされていますか?
update : 私が知りたいのは、複数のプロセスが mmap を介して同じファイルにアクセスしている場合です。それらは同じ物理メモリ部分の書き込みにアクセスします。
ファイルをメモリにマップするときは、システム コールが必要です。ファイルへの後続のアクセスにはシステム コールが必要ですか、それともプロセスの仮想メモリ ページはメモリ内の実際のページ キャッシュにマップされていますか?
update : 私が知りたいのは、複数のプロセスが mmap を介して同じファイルにアクセスしている場合です。それらは同じ物理メモリ部分の書き込みにアクセスします。
ファイルを mmap すると、Linux は MMU (メモリ管理ユニット) にエントリを作成します。MMU は、CPU から実 RAM へのすべての読み取りと書き込みを監視します。このようにして、返されたメモリの部分にいつアクセスするかがわかりますmmap()
。実際の RAM にまだない部分を読み取ると、ページ フォールトが発生します。MMU はそれらをキャッチし、カーネル ルーチンを呼び出してファイルの適切な部分を RAM のどこかにロードし、MMU テーブルのエントリを更新して、データがmmap()
与えられたアドレスに配置されているように見せます。実際、それは別の場所にありますが、MMU はこれを完全に透過的にします。
メモリに書き込むと、MMU は変更されたページを「ダーティ」としてマークします。それらがフラッシュされると (より多くのファイルにアクセスするため、または を呼び出すためmunmap()
)、変更がディスクに書き出されます。
そのため、ページ フォールトとダーティ ページ フラッシュが発生するたびに、システム コールが発生します。ただし、ページは 4 または 8 KB であるため、これらはめったに発生しません。また、カーネルは一度に複数のページをロードするため、システム コールの数が再び減少します。最後に、同じコードを使用してスワッピングを実装しているため、非常に最適化されています。
これらすべての効果により、mmap は非常に効率的になります。
(プロセスによる)追加のシステムコールは必要ありません。通常のメモリのようにアクセスするだけです。ファイルの処理が完了したら、 を呼び出すだけmunmap
です。
戻り値
成功
mmap()
すると、マップされた領域へのポインターを返します。エラーの場合、値MAP_FAILED
(つまり、(void *) -1) が返され、errno が適切に設定されます。成功するとmunmap()
0 を返し、失敗すると -1 を返し、errno
(おそらく にEINVAL
) 設定されます。
詳細については、こちらの man ページを参照してください。
明確にするために編集:
関数がファイルを呼び出しプロセスのメモリ空間にマップし、メモリ ブロックの先頭へのポインタを返すと言っているのです。
たとえば、MAP_SHARED
フラグを使用して 2 つの異なるプロセスが同じファイルをマップする場合、各プロセスは同じ物理メモリにアクセスしますが、そのメモリは各プロセスの仮想メモリ空間の異なる場所、つまり mmap によって返されるポインタにマップされる可能性があります。各プロセスの仮想メモリ空間内の値は等しくない場合があります。
これは、たとえば、共有メモリ ブロック内にポインターを格納する必要がある場合、それらのポインターは、ブロック/ファイルの先頭に対するオフセットとして格納されている場合にのみ有用であり、それらは有用に指すことができるだけであるという点を提起します。ブロック/ファイルの内部の場所。