コンピューティングにおいて、は、ファイルまたはデバイスをメモリにマップするPOSIX準拠のUnixシステム コールmmap(2)です。これは、メモリ マップ ファイルI/O の方法です。ファイルの内容はディスクからすぐには読み込まれず、最初は物理 RAM をまったく使用しないため、デマンド ページングが実装されます。ディスクからの実際の読み取りは、特定の場所にアクセスした後に遅延方式で実行されます。マッピングが不要になったら、を使用してポインタをマップ解除する必要があります。保護情報 (たとえば、マップされた領域を実行可能としてマークする) は、を使用して管理でき、特別な処理は、を使用して強制できます。
munmap(2)mprotect(2)madvise(2)
Linux、macOS、BSDでは、複数の種類のマッピングを作成できます。他のオペレーティング システムでは、これらのサブセットのみをサポートする場合があります。たとえば、共有マッピングは、グローバルVFSmmapまたは I/O キャッシュのないオペレーティング システムでは実用的ではない場合があります。
歴史
メモリマップファイルの元々の設計は、TOPS-20オペレーティングシステムに由来しています。mmap関連するシステムコールは、 UnixのBerkeley Software Distribution (BSD)バージョンの一部として設計されました。そのAPIは、4.2BSDシステムマニュアルに既に記載されていましたが、そのリリースにも4.3BSDにも実装されていませんでした。[1] Sun Microsystemsは、このAPIをSunOSオペレーティングシステムに実装していました。カリフォルニア大学バークレー校のBSD開発者は、 Sunに実装の寄贈を要請しましたが、失敗しました。代わりに、4.3BSD-Renoは、 Machの仮想メモリシステムに基づく実装で出荷されました。[2]
ファイルバックアップと匿名
ファイル バックアップ マッピングは、プロセスの仮想メモリの領域をファイルにマップします。つまり、メモリのそれらの領域を読み取ると、ファイルが読み取られます。これはデフォルトのマッピング タイプです。
匿名マッピングは、ファイルの裏付けのないプロセスの仮想メモリ領域をマッピングします。その内容はゼロに初期化されます。[3]この点では、匿名マッピングはmallocに似ており、一部の malloc 実装では、特に大規模な割り当てに使用されます。匿名マッピングは POSIX 標準の一部ではありませんが、ほとんどすべてのオペレーティングシステムでMAP_ANONYMOUSおよびMAP_ANONフラグによって実装されています。
メモリの可視性
マッピングが共有されている場合(MAP_SHAREDフラグが設定されている)、プロセスがフォークされたとき (fork(2)システム コールを使用) にマッピングは保持されます。したがって、1 つのプロセスでマップされた領域に書き込まれた内容は、関連するすべてのプロセス (親、子、または兄弟) ですぐに表示されます。マッピングが共有され、ファイルによってバックアップされている場合 ( ではないMAP_ANONYMOUS)、基礎となるファイル メディアへの書き込みは、msync(2)システム コールに渡された後にのみ保証されます。対照的に、マッピングがプライベートである場合(MAP_PRIVATEフラグが設定されている)、変更は他のプロセスには表示されず、ファイルにも書き込まれません。
基になるファイルから読み取る、または基になるファイルに書き込むプロセスは、ファイルのセグメントが RAM にコピーされ、定期的にディスクにフラッシュされるだけなので、ファイルをマップした別のプロセスと同じデータを常に表示するわけではありません。 の呼び出しで同期を強制できますmsync(2)。
ファイルに対して mmap を使用すると、同じファイルにアクセスするアプリケーションのメモリ オーバーヘッドを大幅に削減できます。つまり、ファイルにアクセスするアプリケーションごとにファイルをロードするのではなく、ファイルが含むメモリ領域を共有できます。つまり、mmap(2) はプロセス間通信(IPC) に使用されることがあります。最近のオペレーティング システムでは、mmap(2) はSystem V IPC共有メモリ機能よりも一般的に好まれます。[4]
System V 共有メモリ (shmem) とメモリ マップ I/O (mmap) の主な違いは、System V 共有メモリは永続的であることです。プロセスによって明示的に削除されない限り、メモリ内に保持され、システムがシャットダウンされるまで使用可能です。mmap されたメモリは、アプリケーションの実行間では永続的ではありません (ファイルによってバックアップされていない限り)。
Cプログラミング言語での使用例
#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <文字列.h>
#include <unistd.h>
/* この例では、/dev/zeroのmmapが次のものと同等であることを示しています。
どのファイルにも接続されていない匿名メモリ (MAP_ANON) を使用しています。
注意:MAP_ANONYMOUSまたはMAP_ANONはほとんどのUNIXでサポートされています。
バージョンにより、/dev/zero の本来の目的が失われます。
*/
/* OS X または macOS では動作しません。/dev/zero に mmap できません */
int main ( void )
{
const char str1 [] = "文字列 1" ;
const char str2 [] = "文字列 2" ;
pid_t parpid = getpid (), childpid ;
整数fd = -1 ;
char *匿名、*ゼロ;
(( fd = open ( "/dev/zero" 、O_RDWR 、0 )) == -1 )の場合
エラー( 1 、"オープン" );
anon = ( char * ) mmap ( NULL , 4096 , PROT_READ | PROT_WRITE , MAP_ANON | MAP_SHARED , -1 , 0 );
ゼロ= ( char * ) mmap ( NULL , 4096 , PROT_READ | PROT_WRITE , MAP_SHARED , fd , 0 );
if (匿名== MAP_FAILED ||ゼロ== MAP_FAILED )
errx ( 1 、"どちらかの mmap" );
strcpy (匿名, str1 );
strcpy (ゼロ, str1 );
printf ( "PID %d: \t anonymous %s、ゼロバック %s \n " 、parpid 、anon 、zero );
スイッチ((子pid = fork ())) {
ケース-1 :
エラー( 1 、"フォーク" );
/* 未到達 */
ケース0 :
子pid = getpid ();
printf ( "PID %d: \t anonymous %s、ゼロバック %s \n " 、childpid 、anon 、zero );
睡眠(3 )
printf ( "PID %d: \t anonymous %s、ゼロバック %s \n " 、childpid 、anon 、zero );
munmap (匿名、4096 );
munmap (ゼロ, 4096 );
閉じる( fd );
EXIT_SUCCESSを返します。
}
睡眠(2 )
strcpy (匿名, str2 );
strcpy (ゼロ, str2 );
printf ( "PID %d: \t anonymous %s、ゼロバック %s \n " 、parpid 、anon 、zero );
munmap (匿名、4096 );
munmap (ゼロ, 4096 );
閉じる( fd );
EXIT_SUCCESSを返します。
}
サンプル出力:
PID 22475: 匿名文字列 1、ゼロバック文字列 1 PID 22476: 匿名文字列 1、ゼロバック文字列 1 PID 22475: 匿名文字列 2、ゼロバック文字列 2 PID 22476: 匿名文字列 2、ゼロバック文字列 2
データベース実装での使用
mmapシステムコールは、バッファプールを実装する代替手段としてさまざまなデータベース実装で使用されてきましたが、これにより、現実的にはバッファプールを使用することでのみ解決できる別の一連の問題が発生しました。[5]
参照
- 物理メモリよりもアドレス空間が大きい場合の仮想メモリ
- 仮想メモリの実装のためのページング
- mmap が利用するディスク キャッシュ メカニズムのページ キャッシュ
- mmap によって実装されたスキームの要求ページング
参考文献
- ^ William Joy ; Eric Cooper; Robert Fabry ; Samuel Leffler ; Kirk McKusick ; David Mosher (1983). 4.2BSD システムマニュアル(PDF) (レポート).コンピュータシステム研究グループ、カリフォルニア大学バークレー校。
- ^ McKusick、Marshall Kirk (1999)。「Berkeley Unix の 20 年: AT&T 所有から自由に再配布可能へ」。オープン ソース: オープン ソース革命からの声。O'Reilly。
- ^ 「mmap(2) - Linuxマニュアルページ」。
- ^ Kerrisk, Michael (2010). Linux プログラミングインターフェース: Linux および UNIX システムプログラミングハンドブック. サンフランシスコ: No Starch Press. p. 1116. ISBN 978-1-59327-291-3. OCLC 728672600.
- ^ 「データベース管理システムで MMAP を使用しますか?」db.cs.cmu.edu 。 2023 年 7 月 4 日閲覧。
さらに読む
- POSIX標準からの説明
- 違い:
- ドラゴンフライBSD
- フリーBSD
- ネットBSD
- オープンBSD
- イルモス
- Mac OS X
- ソラリス
- HP-UX
- QNX
- ウィンドウズ
- MapViewOfFile win32 関数は、mmap とほぼ同等です。
- その他のソースコードの例:
- SharedHashFile、mmap() を使用して実装されたオープンソースの共有メモリハッシュテーブル。
