Closed kawasin73 closed 5 years ago
fsync()
と msync()
の違いmmap の共有ファイルマッピングでは、複数のプロセスで同じページキャッシュを利用するが、Linux の場合通常のファイルIOで使われるページキャッシュを利用する。
現代の多くのUNIXシステム同様に Linux でも統合仮想メモリとでも言えるメモリ管理方式を実装しています。この方式では、可能ならば、メモリマッピングとバッファキャッシュは物理メモリの同じページを共有します。すなわち、マッピングにおるファイル内容の参照と I/O システムコールによるファイル内容の参照(
read()
、write()
など)は常に一意であり、msync()
の意味はマッピングをディスクへ強制的に書き出すことしかありません。「LINUXプログラミングインターフェース」より p.1090「49.5 マッピング領域とファイルの同期:msync()」
そのため Linux では、fsync()
を呼び出すことで mmap のマッピングをディスクに書き込むことができる。
ファイルIOで使われるページキャッシュと異なるシステムの場合は、msync()
を MS_SYNC
オプションで呼び出すか、msync()
を MS_ASYNC
で呼び出した(マッピングとカーネルのバッファキャッシュを同期させる)後に、fsync()
を呼び出すことでディスクへ書き込むことができる。
また munmap()
、close()
では、ディスクへの書き込み完了は保障されないため、msync()
または、fsync()
を呼び出す必要がある。
また、fsync()
は、変更された部分のページをディスクデバイスへ書き込むため、msync()
と挙動が同じになる。
fsync() は、ファイルディスクリプター fd で参照されるファイルの、メモリー内で存在す る修正されたデータ (つまり修正されたバッファーキャッシュページ) を、ディスクデ バイス(またはその他の永続ストレージデバイス) に転送 (「フラッシュ」) し、これ により、システムがクラッシュしたり、再起動された後も、変更された全ての情報が 取り出せるようになる。 https://linuxjm.osdn.jp/html/LDP_man-pages/man2/fsync.2.html
Go 言語では、
syscall
パッケージにsyscall.Mmap()
とsyscall.Munmap()
が用意されているが、msync
に相当するインターフェイスは用意されていない。一方、Mmap を実行する時にはファイルディスクリプタが必要になるが、ファイルディスクリプタを提供する
os.File
構造体はSync()
インターフェイスを用意しており、内部でfsync
システムコールを実行している。mmap した内容がディスクに書き込まれたことを保証するために、
fsync
を利用することができるかどうかを調査する。