Unixファミリーシステムでメモリマッピング(mmap()システムコールを介して実装されている)の概念を理解できるように説明できる人はいますか?この機能はいつ必要ですか?
答え1
考慮事項:2つのプロセスが同時に読み書きするために同じファイルを開くことができるため、2つの間にある種の通信がある可能性があります。
プロセスAがファイルに書き込むとき、最初に独自のプロセス固有のメモリ内のバッファをいくつかのデータで埋め、次にこの関数を呼び出してそのバッファをwrite
カーネルが所有する他のバッファにコピーします(実際にはページキャッシュエントリになります)。カーネルはダーティとしてマークされ、最終的にディスクに書き戻されます。
プロセスBは、同じファイルの同じポイントから読み取られます。read
データは、ページキャッシュ内の同じ位置でBメモリのバッファにコピーされる。
2 つのコピーが必要です。まず、データはAから「共有」メモリにコピーされ、次に「共有」メモリからBにコピーされます。
mmap
Aを使用すると、ページキャッシュを独自のアドレス空間で直接使用できます。これで、中間バッファを埋めるのではなく、データを同じ「共有」メモリに直接フォーマットしてコピーを避けることができます。
同様に、Bはmmap
ページを直接それアドレス空間。これで、Aが「共有」メモリに入れるすべてを別々のバッファにコピーせずに直接アクセスできます。
(明らかに、このシナリオをIPCで使用するにはある種の同期が必要ですが、これは範囲外です。)
ここで、Aがファイルが保存されているデバイスのドライバに置き換えられる場合を考えてみましょう。 、Bを使ってmmap
ファイルにアクセスします。まだ重複コピー(DMAまたはその他入力するページのキャッシュは避けられませんが、複製は必要ありません。再びBのバッファに入れます)。
もちろん、いくつかの欠点があります。たとえば、
デバイスとOSが非同期ファイルI / Oをサポートしている場合は、それを使用して読み取り/書き込みブロックを回避できます。ただし、マップされたページを読み書きすると、直接処理できないブロックページエラーが発生する可能性があります。それを避けるためになどを使用
mincore
)ファイルの終わりを読み取ろうとするのを防ぎ、または良い方法でファイルに追加するのに役立ちます(長さを確認するか、明示的に
truncate
ファイルを増やす必要があります)。