Open Source Web Development Tutorials - Dev Shed
mmap()を利用する高度なファイルI/O
(2009/03/18公開)
ファイルとマッピングの同期化
POSIXは、以下のとおり、第2章で解説したfsync()システムコールに相当するメモリマッピングを提供します。
#include <sys/mman.h>
int msync (void *addr, size_t len, int flags);
msync()のコールは、mmap()によってマッピングしたファイルへのあらゆる変更をディスクにフラッシュして、マッピングとマッピングされるファイルを同期化します。厳密には、メモリアドレスaddr から開始しlenバイトにかけて継続するマッピングに関連付いたファイルあるいはファイルのサブセットが、ディスクと同期化します。Addr引数はページ境界に合っている必要があります。通常は、前のmmap()呼び出しの戻り値です。
msync()を呼び出さない場合は、ファイルのマッピングが削除されるまで、ダーティーなマッピングがディスクに書き戻される保証はありません。これはwrite()の動作とは異なります。write()では、書き込みプロセスの一環としてバッファがダーティーとなり、ディスクへの書き戻しが待ち行列に入ります。メモリ・マッピングへ書き込む場合は、カーネルが関与することなく、カーネルのページ・キャッシュにあるファイルのページが直接変更されます。カーネルは、すぐにはページ・キャッシュやディスクと同期化しない可能性があります。
同期化の動作を制御するFlagsパラメータは、以下の値のビット単位ORです。
MS_ASYNC
同期化が非同期的に発生することを指示します。更新予定を定めますが、msync()のコールは、書き込みの実行を待たず、直ちに戻ります。
MS_INVALIDATE
マッピングのそのほかすべてのキャッシュされたコピーを無効とするように指示します。この後、ファイルのすべてのマッピングに対して発生するすべてのアクセスで、新規に同期化されたディスク上のコンテンツが反映されます。
MS_SYNC
同期化が同期的に発生することを指示します。msync()コールは、すべてのページがディスクに書き戻されるまで戻りません。
MS_ASYNCあるいはMS_SYNCのいずれか一方を指示しなくてはなりません。両方を指示することはできません。
以下のとおり、使い方は簡単です。
if (msync (addr, len, MS_ASYNC) == -1)
perror ("msync");
上記の例は、非同期的に、 [addr,addr+len)領域にマッピングされたファイルをディスクに同期化(おそらく10倍の速度です)します。
msync()が成功すると、ゼロが戻ります。失敗すると-1が戻り、適切なerrnoが示されます。有効なerrno値は以下のとおりです。
EINVAL
FlagsパラメータにMS_SYNCとMS_ASYNCの両方が指示されています。あるいは、3つの有効なフラグのいずれか以外のビットが設定されています。あるいは、addrがページ境界に合っていません。
ENOMEM
指示されたメモリ領域(あるいはその一部)がマッピングされていません。Linuxでは、一部がマッピング削除されている領域の同期化を要求した場合、POSIXに従がってENOMEMを戻しますが、領域内のすべての有効なマッピングを同期化する点に留意してください。
2.4.19バージョンより前のLinuxカーネルでは、msync()はENOMEMの代わりにEFAULTを戻していました。
Copyright © 2008 Ziff Davis Enterprise, Inc.
Originally appearing in the U.S. Edition of Dev Shed. All Rights Reserved.








