Provided by: manpages-ja-dev_0.5.0.0.20131015+dfsg-2_all bug

名前

       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 に残り続けることが保証される。

       munlock()   は、  addr から始まる長さ len バイトのアドレス範囲のページのロックを解除する。 この呼び出しを
       行った後は、カーネルが、指定されたメモリ範囲を含む   全てのページを外部のスワップ空間に移動できるようにな
       る。

   mlockall()  munlockall()
       mlockall()   は呼び出し元プロセスのアドレス空間にマップされている全てのページを  ロックする。これにはコー
       ド、データ、スタックの 各セグメント、共有ライブラリ、カーネルのユーザー空間データ、  共有メモリ、メモリ・
       マップされたファイルが含まれる。 システム・コールが成功した場合には全てのマップされたページは RAM に 残る
       ことを保証される。 これらのページは後でロック解除されるまで RAM に残り続けることが保証される。

       flags 引数は以下の内容の一つまたは複数のビット OR から構成される:

       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) を呼び出すことで決定できる。

       mlockall()  と munlockall()  が利用可能な POSIX システムでは、 _POSIX_MEMLOCK<unistd.h> で 0 より大き
       い値に定義されている (sysconf(3)  も参照のこと)。

注意

       メモリのロックの用途としては主に二つある: リアルタイム アルゴリズムと高いセキュリティの必要なデータ処理で
       ある。リアルタイムの  アプリケーションは決定的なタイミングやスケジューリングを必要とするが、 ページングは
       予期しないプログラムの実行遅延をもたらす主要な要因となる。     リアルタイムのアプリケーションはたいていは
       sched_setscheduler(2)   でリアルタイムスケジューラに変更される。 暗号やセキュリティのソフトウェアはしばし
       ばパスワードや秘密鍵のデータの ような重要なバイト列を扱う。ページングの結果、これらの秘密が  スワップ用の
       固定媒体に転送されるかもしれない。そして、セキュリティ・  ソフトウェアが  RAM  上の秘密を削除して終了した
       ずっと後になっても、 このスワップされたデータには敵がアクセスできる可能性がある (しかし、ラップトップとい
       くつかのデスクトップコンピュータの サスペンドモードはシステムの RAM の内容をメモリのロックに関わらず ディ
       スクに保存することに注意)。

       リアルタイムプロセスが mlockall()  を使ってページフォールトによる遅延を防ごうとする場合、  関数呼び出しに
       よってページフォールトが発生しないように、 時間制限の厳しい部分 (time-critical section) に入る前に 十分な
       量のロックされたスタックを確保しておく必要がある。 これを実現するには、十分な大きさの自動変数 (の配列) を
       確保し、  これらのスタック用のページがメモリ上に確保されるようにこの配列に 書き込みを行う関数を用意し、こ
       れを呼び出せばよい。こうすることで、 十分な量のページがスタックにマッピングされ、RAM にロックされる。  ダ
       ミーの書き込みを行うことによって、  時間制限の厳しい部分  (critical section) 内では書き込み時コピーによる
       ページフォールトさえも発生しないことが保証される。

       メモリロックは fork(2)  で作成された子プロセスには継承されず、 execve(2)   が呼ばれたり、プロセスが終了し
       た場合は 自動的に削除される (ロック解除される)。

       あるアドレス範囲に対するメモリロックは、そのアドレス範囲が  munmap(2)  によってアンマップされた場合は削除
       される。

       メモリのロックは累積しない。 すなわち複数回 mlock()  や mlockall()   を呼び出してロックされたページでも、
       対応する範囲に対して  munlock()  を 1 回呼び出したり munlockall()  を呼び出したりするだけでロック解除され
       る。 複数の場所や複数のプロセスにマップされているページは、少なくとも一つの場所、  一つのプロセスでロック
       されている限りは RAM に残り続ける。

   Linux での注意
       Linux では、 mlock()  と munlock()  は自動的に addr を端数切り捨てにより一番近いページ境界へと丸める。 し
       かし POSIX.1-2001 は addr がページ境界に合っていることを要求する実装も許している。 そのため移植性を意図し
       たアプリケーションではきちんと境界に合わせた方が良い。

       Linux  固有の  /proc/PID/status  ファイルの  VmLck  フィールドには、  mlock(),  mlockall() および mmap(2)
       MAP_LOCKED を使って、 ID が PID のプロセスがロックしているメモリ量 (キロバイト単位) が 表示される。

   制限と権限
       Linux   2.6.8   以前では、メモリをロックするためには特権   (CAP_IPC_LOCK)    が必要で、    ソフト資源制限
       RLIMIT_MEMLOCK はプロセスがどれだけのメモリをロックできるかの制限を定義する。

       Linux   2.6.9  以降では、特権を持つプロセスがロックできるメモリ量は無制限となり、  代わりにソフト資源制限
       RLIMIT_MEMLOCK は特権を持たないプロセスがロックできるメモリ量の制限を定義する。

バグ

       2.4.17 までの 2.4 シリーズの Linux カーネルには、 mlockall()  MCL_FUTURE フラグが fork(2)  で継承されると
       言うバグがある。 これはカーネル 2.4.18 で修正された。

       カーネル 2.6.9 以降では、特権を持ったプロセスが mlockall(MCL_FUTURE) を呼び出した後で、特権をなくした場合
       (例えば、 実効 UID を 0 以外の値に変更するなどにより、 CAP_IPC_LOCK ケーパビリティを失った場合)、リソース
       上限 RLIMIT_MEMLOCK に達すると、それ以降のメモリ割り当て (例えば mmap(2), brk(2))  は失敗する。

関連項目

       mmap(2), setrlimit(2), shmctl(2), sysconf(3), proc(5), capabilities(7)

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 3.54 の一部 である。プロジェクトの説明とバグ報告
       に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。