mmap()とは
mmap()は、
UNIX系OSで利用可能な
システムコールの一つで、ファイルやデバイスなどのリソースを
プロセスの仮想
アドレス空間にマッピングする機能を提供します。これにより、ファイルの内容をメモリ上に展開し、直接アクセスすることが可能になります。従来のストリームI/Oと比較して、データ転送の効率が向上するメリットがあります。
mmap()の主な特徴
仮想アドレス空間へのマッピング: ファイルやデバイスの内容を、
プロセスの仮想
アドレス空間に連続した領域として割り当てます。
効率的なデータアクセス: メモリ上のデータと同様に、直接読み書きが可能となり、データ転送のオーバーヘッドを削減できます。
メモリマップドI/O|メモリマップドI_O: デバイスの制御において、メモリを介して直接アクセスする
メモリマップドI/O|メモリマップドI_Oを実現する手段として用いられます。
共有メモリ: 複数の
プロセス間で同じメモリ領域を共有し、
プロセス間通信に利用できます。
mmap()の利用シーン
ファイルアクセス: 大容量ファイルの読み込みや書き込みを効率的に行うために利用されます。
デバイス制御: デバイスドライバから、
ハードウェアを直接制御するための
メモリマップドI/O|メモリマップドI_Oを実現するために利用されます。
プロセス間通信: 複数の
プロセスでメモリを共有することで、高速なデータ交換を実現するために利用されます。
メモリ管理: OSが追加のメモリ領域を確保するために利用されます。
ファイルマッピングと無名マッピング
mmap()には、ファイルの内容をマッピングする「ファイルマッピング」と、ファイルに紐づかないメモリ領域をマッピングする「無名マッピング」の2種類があります。
ファイルマッピング: ファイルをメモリ上に展開し、ファイルの内容を直接操作できます。`MAP_SHARED`を指定すると、複数の
プロセスで変更を共有できます。`MAP_PRIVATE`を指定した場合は、
コピーオンライト方式で、変更はファイルには反映されません。
無名マッピング: ファイルに紐づかないメモリ領域を確保し、
プロセスが自由に利用できます。`MAP_ANONYMOUS`を指定することで利用できます。`malloc()`などのメモリ確保関数が内部的に利用することもあります。
複数プロセス間におけるmmap
複数の
プロセスが同じリソースをマッピングする場合、`MAP_SHARED`を指定するとメモリ領域が共有され、ある
プロセスが書き込んだ内容を他の
プロセスが読み取ることができます。`MAP_PRIVATE`を指定すると、
コピーオンライト方式で、書き込みが発生するまでメモリ領域は共有されます。
`fork()`で生成された子
[プロセス]]は、親プロセスのメモリを通常は継承しますが、`mmap()`でマップした領域は、`minherit()`を呼び出すことで、継承しないようにしたり、ゼロクリアしたりすることができます。これにより、[[暗号論的擬似乱数生成器]などの機密情報を扱う場合に、セキュリティを確保することができます。
アドレス指定
通常、`mmap()`は利用可能な仮想
アドレス空間を自動的に割り当てますが、`MAP_FIXED`を指定することで、特定のアドレスを指定することができます。ただし、アドレスはページサイズの倍数である必要があり、アドレス0は使用できません。
各OSにおけるmmap()の提供
mmap()は
POSIX標準で定義されており、多くの
UNIX系OSで利用できます。
LinuxやFreeBSDなどのOSでは、OS固有の拡張機能が提供されています。Windowsでは、`CreateFileMapping()`や`MapViewOfFile()`などのAPIが、同様の機能を提供しています。
まとめ
mmap()は、ファイルやデバイスの効率的なアクセス、
プロセス間通信、メモリ管理など、さまざまな場面で利用される重要な
システムコールです。データ転送のオーバーヘッドを削減し、高速な処理を実現するための強力なツールです。
POSIX標準で定義され、多くのOSで利用可能であり、各OSで拡張機能も提供されています。