あなたが詳細を与えなかったので、私はあなたがUnixライクなシステムの振る舞いに興味があると思います。
実際open()
には、システムコールはファイル記述子のみを作成し、それをまたはのいずれかで使用できmmap()
ますread()
。
メモリマップドI/Oと標準I/Oはどちらも、I / O操作の数を減らすためにファイルがキャッシュされるバッファであるページキャッシュを介して、ディスク上のファイルに内部的にアクセスします。
標準のI/Oアプローチ(write()
およびを使用read()
)では、システムコールを実行し、ページキャッシュから(または書き込み中の場合は)アプリケーションによって選択されたバッファーにデータをコピーします。その非順次アクセスに加えて、別のシステムコールが必要lseek()
です。システムコールは高額であり、データのコピーも高額です。
ファイルがメモリマップされる場合、通常、プロセスアドレス空間のメモリ領域はページキャッシュに直接マップされるため、すでにロードされているデータのすべての読み取りと書き込みを追加の遅延なしで実行できます(システムコールやデータコピーは不要)。アプリケーションがまだロードされていないファイル領域にアクセスしようとした場合にのみ、ページフォールトが発生し、カーネルが必要なデータ(ページ全体)をディスクからロードします。
編集:メモリページング
についても説明する必要があることがわかります。最新のアーキテクチャのほとんどには、実際のハードウェアである物理メモリと、プロセスのアドレス空間を作成する仮想メモリがあります。カーネルは、仮想メモリ内のアドレスを物理メモリ内のアドレスにマップする方法を決定します。最小単位はメモリページです(通常、ただし常に4Kであるとは限りません)。1:1マッピングである必要はありません。たとえば、すべての仮想メモリページを同じ物理アドレスにマッピングできます。
メモリマップドI/Oでは、アプリケーションのアドレス空間とカーネルのページキャッシュが同じ物理メモリ領域にマップされるため、プログラムはページキャッシュに直接アクセスできます。