Unix-system-calls-mlockall

提供:Dev Guides
移動先:案内検索

[top]#

[[File:]]

[[File:]]

|Web |This Site

  • 初心者向けのUnix *
  • 高度なUnix *

選択した読書

Copyright©2014 by finddevguides

  Home     References     Discussion Forums     About TP  

mlock()-Unix、Linuxシステムコール

[[File:]] image :http://www.finddevguides.com/images/next.gif [next] image:http://www.finddevguides.com/add- this.gif [AddThisソーシャルブックマークボタン]

広告

NAME

mlock、munlock、mlockall、munlockall-メモリのロックとロック解除

概要

#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_引数は、次の定数の1つ以上のビット単位のORとして構築されます。

Tag

説明

*MCL_CURRENT*

現在プロセスのアドレス空間にマップされているすべてのページをロックします。

*MCL_FUTURE*

将来的にプロセスのアドレス空間にマップされるすべてのページをロックします。 これらは、たとえば、増加するヒープとスタックに必要な新しいページや、新しいメモリマップファイルまたは共有メモリ領域になります。

*MCL_FUTURE* が指定されている場合、その後のシステムコール(たとえば、 *mmap* (2)、 *sbrk* (2)、 *malloc* (3))は、ロックされたバイト数が許可された最大値を超えます(以下を参照)。 同じ状況で、スタックの成長も同様に失敗する可能性があります。カーネルはスタックの拡張を拒否し、プロセスに *SIGSEGV* シグナルを送信します。
*munlockall* ()は、呼び出しプロセスのアドレス空間にマップされているすべてのページのロックを解除します。

ノート

メモリロックには、リアルタイムアルゴリズムと高セキュリティデータ処理という2つの主な用途があります。 リアルタイムアプリケーションには確定的なタイミングが必要であり、スケジューリングと同様に、ページングは​​予期しないプログラム実行遅延の主な原因の1つです。 リアルタイムアプリケーションは通常、 sched_setscheduler (2)を使用してリアルタイムスケジューラに切り替えます。 暗号化セキュリティソフトウェアは、多くの場合、パスワードや秘密キーなどの重要なバイトをデータ構造として処理します。 ページングの結果、これらのシークレットは永続的なスワップストアメディアに転送される可能性があり、セキュリティソフトウェアがRAM内のシークレットを消去して終了した後、敵がアクセスできる可能性があります。 (ただし、ラップトップおよび一部のデスクトップコンピューターのサスペンドモードでは、メモリロックに関係なく、システムのRAMのコピーがディスクに保存されることに注意してください。)

*mlockall* ()を使用してページフォールトの遅延を防ぐリアルタイムプロセスは、タイムクリティカルセクションに入る前にロックされたスタックページを十分に予約して、関数呼び出しによってページフォールトが発生しないようにする必要があります。 これは、十分な大きさの自動変数(配列)を割り当てる関数を呼び出して、これらのスタックページにアクセスするためにこの配列が占有するメモリに書き込むことで実現できます。 これにより、スタックに十分なページがマップされ、RAMにロックできます。 ダミー書き込みにより、クリティカルセクションでコピーオンライトページフォールトが発生することはありません。

メモリロックは、 fork (2)で作成された子には継承されず、 execve (2)またはプロセスの終了時に自動的に削除(ロック解除)されます。

アドレス範囲が munmap (2)によってマップ解除されると、アドレス範囲のメモリロックは自動的に削除されます。

メモリロックはスタックしません。つまり、 mlock ()または mlockall ()の呼び出しによって数回ロックされたページは、対応する範囲の munlock ()の1回の呼び出しまたは munlockallによってロック解除されます。 ()。 複数の場所または複数のプロセスによってマップされたページは、少なくとも1つの場所または少なくとも1つのプロセスによってロックされている限り、RAMにロックされたままになります。

Linuxノート

Linuxでは、 mlock ()および munlock ()は、_addr_を最も近いページ境界に自動的に切り捨てます。 ただし、POSIX.1-2001では、_addr_をページに揃えることを実装で要求できるため、移植可能なアプリケーションでこれを保証する必要があります。

制限と権限

Linux 2.6.8以前では、メモリをロックするにはプロセスが特権( CAP_IPC_LOCK )である必要があり、 RLIMIT_MEMLOCK ソフトリソース制限はプロセスがロックできるメモリ量の制限を定義します。

Linux 2.6.9以降、特権プロセスがロックできるメモリ量に制限はなく、代わりに RLIMIT_MEMLOCK ソフトリソース制限は、非特権プロセスがロックできるメモリ量の制限を定義します。

返り値

成功すると、これらのシステムコールは0を返します。 エラーの場合、-1が返され、_errno_が適切に設定され、プロセスのアドレス空間内のロックは変更されません。

エラー

Tag

説明

*ENOMEM*

(Linux 2.6.9以降)呼び出し元にゼロ以外の RLIMIT_MEMLOCK ソフトリソース制限がありましたが、許可された制限より多くのメモリをロックしようとしました。 プロセスが特権( CAP_IPC_LOCK )の場合、この制限は適用されません。

*ENOMEM*

(Linux 2.4以前)呼び出しプロセスは、RAMの半分以上をロックしようとしました。

*EPERM*

(Linux 2.6.9以降)呼び出し元には特権がなく( CAP_IPC_LOCK )、その RLIMIT_MEMLOCK ソフトリソース制限は0でした。

*EPERM*

(Linux 2.6.8以前)呼び出しプロセスには、 munlockall ()を呼び出すための十分な特権がありません。 Linuxでは、 CAP_IPC_LOCK 機能が必要です。

*mlock* ()および *munlock* ()の場合:
*EINVAL*

_len_は負でした。

*EINVAL*

(Linuxではありません)_addr_はページサイズの倍数ではありませんでした。

*ENOMEM*

指定されたアドレス範囲の一部が、プロセスのアドレス空間内のマップされたページに対応していません。

*mlockall* ()の場合:
*EINVAL*

不明な_flags_が指定されました。

*munlockall* ()の場合:
*EPERM*

(Linux 2.6.8以前)呼び出し元には特権がありません( CAP_IPC_LOCK )。

BUGS

2.4.17以前の2.4シリーズLinuxカーネルでは、バグにより mlockall () MCL_FUTURE フラグが fork (2)に継承されていました。 これはカーネル2.4.18で修正されました。

カーネル2.6.9以降、特権プロセスが_mlockall(MCL_FUTURE)_を呼び出し、その後特権を削除した場合(たとえば、有効なUIDをゼロ以外の値に設定することで CAP_IPC_LOCK 機能を失った場合)、その後のメモリ割り当て(例: 、 mmap (2)、 brk (2))は、 RLIMIT_MEMLOCK リソース制限に遭遇すると失敗します。

可用性

*mlock* ()および *munlock* ()が利用可能なPOSIXシステムでは、 *_ POSIX_MEMLOCK_RANGE* は<unistd.h>で定義され、ページのバイト数は定数 *PAGESIZE* (定義されている場合)から決定できます。 )<limits.h>で、または_sysconf(_SC_PAGESIZE)_を呼び出して。
*mlockall* ()および *munlockall* ()が使用可能なPOSIXシステムでは、 *_ POSIX_MEMLOCK* が<unistd.h>で0より大きい値に定義されています。 ( *sysconf* (3)も参照してください。)

準拠

POSIX.1-2001、SVr4

関連項目

[[File:]] image :http://www.finddevguides.com/images/next.gif [next] [[File:]]

広告

  
Advertisements