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