2.3. mlock() システムコール
メモリーロック (mlock()) システムコールを使用すると、呼び出しプロセスがアドレス空間の指定された範囲をロックまたはロック解除できるようになり、Linux がロックされたメモリーをスワップ空間にページングするのを防ぐことができます。物理ページをページテーブルエントリーに割り当てると、そのページへの参照は比較的高速になります。メモリーロックシステムコールは、mlock() および munlock() カテゴリーに分類されます。
mlock および munlock システムコールは、特定の範囲のプロセスアドレスページをロックおよびロック解除します。成功すると、指定された範囲内のページは、munlock() システムコールがページのロックを解除するまで、メモリーに常駐したままになります。
mlock() および munlock() システムコールは、次のパラメーターを取ります。
-
addr: アドレス範囲の開始を指定します。 -
len: アドレス空間の長さをバイト単位で指定します。
成功すると、mlock() および munlock() システムコールは 0 を返します。エラーの場合は、-1 を返し、エラーを示す errno を設定します。
mlockall() および munlockall() システムコールは、すべてのプログラム空間をロックまたはロック解除します。
mlock() システムコールは、プログラムがページ I/O を持たないことを保証しません。データがメモリー内にとどまることを保証しますが、同じページにとどまることを保証することはできません。move_pages やメモリーコンパクタなどの他の関数は、mlock() の使用に関係なくデータを移動できます。
メモリーロックはページベースで行われ、スタックしません。動的に割り当てられた 2 つのメモリーセグメントが、mlock() または mlockall() によって 2 回ロックされた同じページを共有している場合、1 つの munlock() または munlockall() システムコールを使用してロックを解除します。そのため、二重ロックまたは単一ロック解除の問題を回避するために、アプリケーションがロック解除するページに注意することが重要です。
以下は、二重ロックまたは単一ロック解除の問題を軽減するための最も一般的な 2 つの回避策です。
- 割り当てられたメモリー領域とロックされたメモリー領域を追跡し、ページのロックを解除する前にページ割り当ての数を検証するラッパー関数を作成します。これは、デバイスドライバーで使用されるリソースカウントの原則です。
- ページの二重ロックを回避するために、ページサイズと配置に基づいてメモリーを割り当てます。