MLOCK(2) | Linux Programmer's Manual | MLOCK(2) |
名前
mlock -メモリのロックとロック解除を行う書式
#include <sys/mman.h>
int mlock(const void * addr , size_t len );
int munlock(const void * addr , size_t len );
int mlockall(int flags );
int munlockall(void);
説明
mlock() と mlockall() はそれぞれ、呼び出し元プロセスの仮想アドレス空間の一部または全部を RAM 上にロックし、メモリがスワップエリアにページングされるのを防ぐ。 munlock() と munlockall() は逆の操作で、それぞれ呼び出し元プロセスの仮想アドレス空間の一部または全部をロック解除する。つまり、指定された仮想アドレス範囲のページはカーネルメモリマネージャーから要求されればスワップアウトするようになる。メモリのロックとロック解除はページ単位で行われる。mlock() と munlock()
mlock() は addr から始まる長さ len バイトのアドレス範囲のページをロックする。呼び出しが成功した場合には、指定されたアドレス範囲を含む全てのページは RAM に残り続けることが保証される。これらのページは後でロック解除されるまで RAM に残り続けることが保証される。mlockall() と munlockall()
mlockall() は呼び出し元プロセスのアドレス空間にマップされている全てのページをロックする。これにはコード、データ、スタックの各セグメント、共有ライブラリ、カーネルのユーザー空間データ、共有メモリ、メモリ・マップされたファイルが含まれる。システム・コールが成功した場合には全てのマップされたページは RAM に残ることを保証される。これらのページは後でロック解除されるまで RAM に残り続けることが保証される。- MCL_CURRENT
- 現在、プロセスのアドレス空間にマップされている全てのページをロックする。
- MCL_FUTURE
- 将来、プロセスのアドレス空間にマップされる全てのページをロックする。例えば、ヒープ (heap) やスタックの成長により新しく必要になったページだけでなく、新しくメモリマップされたファイルや共有メモリ領域もロックされる。
MCL_FUTURE が指定されていると、以後のシステムコール (例えば、 mmap(2), sbrk(2), malloc(3)) は、ロックするバイト数が許可された最大値 (下記参照) を超えた場合に失敗する可能性がある。同様に、スタックの成長も失敗する可能性がある。その場合、カーネルはスタックの拡張を拒否し、 SIGSEGV をプロセスに送る。
munlockall() は、呼び出し元プロセスのアドレス空間にマッピングされている全てのページをロック解除する。
返り値
成功した場合は、これらのシステムコールはゼロを返す。エラーの場合は-1 が返され、 errno が適切に設定され、プロセスのアドレス空間におけるロックは変更されない。エラー
- ENOMEM
- (Linux 2.6.9 以降) 呼び出し元は非ゼロのソフト資源制限 RLIMIT_MEMLOCK を持つが、制限が許可している以上のメモリをロックしようとした。この制限は、プロセスが特権 ( CAP_IPC_LOCK) を持っている場合は適用されない。
- ENOMEM
- (Linux 2.4 以前) 呼び出し元プロセスが RAM の半分以上をロックしようとした。
- EPERM
- 呼び出し側が特権を持っていないが、要求された操作を実行するには特権 ( CAP_IPC_LOCK) が必要である。
mlock() と munlock() 用として:
- EAGAIN
- 指定されたアドレス範囲の一部または全てをロックすることができなかった。
- EINVAL
- start+ len の加算の結果が start よりも小さかった (例えば、加算でオーバーフローが発生したなど)。
- EINVAL
- (Linux ではこの意味で使われない) addr がページサイズの倍数ではない。
- ENOMEM
- 指定されたアドレス範囲がプロセスのアドレス空間にマップされたページと一致しない。
mlockall() 用として:
- EINVAL
- 未知の flags が指定された。
munlockall() 用として:
- EPERM
- (Linux 2.6.8 以前) 呼び出し元が権限 ( CAP_IPC_LOCK) を持っていない。
準拠
POSIX.1-2001, SVr4.可用性
mlock() と munlock() が使用可能な POSIX システムでは _POSIX_MEMLOCK_RANGE が <unistd.h> で定義されている。また、ページあたりのバイト数は、 <limits.h> で定義される定数 PAGESIZE から (定義されている場合)、もしくは sysconf(_SC_PAGESIZE) を呼び出すことで決定できる。注意
メモリのロックの用途としては主に二つある: リアルタイムアルゴリズムと高いセキュリティの必要なデータ処理である。リアルタイムのアプリケーションは決定的なタイミングやスケジューリングを必要とするが、ページングは予期しないプログラムの実行遅延をもたらす主要な要因となる。リアルタイムのアプリケーションはたいていは sched_setscheduler(2) でリアルタイムスケジューラに変更される。暗号やセキュリティのソフトウェアはしばしばパスワードや秘密鍵のデータのような重要なバイト列を扱う。ページングの結果、これらの秘密がスワップ用の固定媒体に転送されるかもしれない。そして、セキュリティ・ソフトウェアが RAM 上の秘密を削除して終了したずっと後になっても、このスワップされたデータには敵がアクセスできる可能性がある (しかし、ラップトップといくつかのデスクトップコンピュータのサスペンドモードはシステムの RAM の内容をメモリのロックに関わらずディスクに保存することに注意)。Linux での注意
Linux では、 mlock() と munlock() は自動的に addr を端数切り捨てにより一番近いページ境界へと丸める。しかし POSIX.1-2001 は addr がページ境界に合っていることを要求する実装も許している。そのため移植性を意図したアプリケーションではきちんと境界に合わせた方が良い。制限と権限
Linux 2.6.8 以前では、メモリをロックするためには特権 ( CAP_IPC_LOCK) が必要で、ソフト資源制限 RLIMIT_MEMLOCK はプロセスがどれだけのメモリをロックできるかの制限を定義する。バグ
2.4.17 までの 2.4 シリーズの Linux カーネルには、 mlockall() MCL_FUTURE フラグが fork(2) で継承されると言うバグがある。これはカーネル 2.4.18 で修正された。関連項目
mmap(2), setrlimit(2), shmctl(2), sysconf(3), proc(5), capabilities(7)この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.51 の一部である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。2011-09-14 | Linux |