SHMGET(2) | Linux Programmer's Manual | SHMGET(2) |
shmget - System V 共有メモリーセグメントを割り当てる
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
shmget() は key 引き数に対応する System V 共有メモリーセグメントの識別子を返す。 key の値が IPC_PRIVATE の場合、もしくは key に対応する共有メモリーセグメントが存在せず、 shmflg に IPC_CREAT が指定されていた場合、 新しい共有メモリーセグメントを作成する。 作成される共有メモリーセグメントは、 size 引き数の値を PAGE_SIZE の倍数へと切り上げた (round up) 大きさとなる。
shmflg に IPC_CREAT と IPC_EXCL の両方が指定された場合、 key に対応する共有メモリーセグメントが既に存在すると、 shmget() は失敗し、 errno に EEXIST が設定される (これは open(2) に O_CREAT | O_EXCL を指定した場合の動作と同じである)。
shmflg は以下の内容から構成される:
上記のフラグに加えて、 shmflg の下位 9 ビットは、所有者、グループ、その他への許可を指定する。 これらのビットは open(2) の mode 引き数と同じ形式で同じ意味を持つ。 今のところ、システムは実行 (execute) 許可を参照しない。
共有メモリーセグメントが新たに作成される際、 共有メモリーセグメントの内容は 0 で初期化され、 関連情報を保持するデータ構造体 shmid_ds は以下のように初期化される。
共有メモリーセグメントが既に存在する場合、アクセス許可の検査と、 破壊 (destruction) マークがつけられていないかのチェックが行われる。
成功の場合、有効な共有メモリーセグメントの識別子が返される。 エラーの場合、 -1 が返り、 errno にエラーを示す値が設定される。
失敗した場合は errno が以下のどれかに設定される:
SVr4, POSIX.1-2001.
SHM_HUGETLB と SHM_NORESERVE は Linux での拡張である。
Linux や POSIX の全てのバージョンでは、 <sys/types.h> と <sys/ipc.h> のインクルードは必要ない。しかしながら、いくつかの古い実装ではこれらのヘッダーファイルのインクルードが必要であり、 SVID でもこれらのインクルードをするように記載されている。このような古いシステムへの移植性を意図したアプリケーションではこれらのファイルをインクルードする必要があるかもしれない。
IPC_PRIVATE はフラグではなく key_t 型である。 この特別な値が key に使用された場合は、 shmget() は shmflg の下位 9 ビットを除いた全てを無視し、 新しい共有メモリーセグメントを作成する。
shmget() コールに影響する共有メモリーセグメント資源の制限は以下の通りである:
Linux では、この上限値は /proc/sys/kernel/shmall 経由で参照したり、変更したりできる。 Linux 3.16 以降では、 この上限値のデフォルト値は以下のとおりである。
ULONG_MAX - 2^24
この値は割り当てに関する上限としては適用されない (なお、この値は 32 ビットシステムにも 64 ビットシステムにも適したものになっている)。 ULONG_MAX ではなく、この値が選ばれたのは、 古いアプリケーションが最初に現在の値を確認せずに既存の上限をそのまま増やしてしまっても問題が起こらないようなデフォルト値を選んだからである。 このようなアプリケーションでは、 上限を ULONG_MAX に設定すると値がオーバーフローしてしまうことになる。
Linux 2.4 から Linux 3.15 では、この上限のデフォルト値は以下であった。
SHMMAX / PAGE_SIZE * (SHMMNI / 16)
SHMMAX と SHMMNI が変更されないとすると、 この式の結果に (バイト単位の値を得るために) ページサイズを掛け算すると、 全ての共有メモリーセグメントで使用される全メモリーの上限として、 8 GB という値が得られる。
Linux では、この上限値は /proc/sys/kernel/shmmax 経由で参照したり、変更したりできる。 Linux 3.16 以降では、 この上限値のデフォルト値は以下のとおりである。
ULONG_MAX - 2^24
この値は割り当てに関する上限としては適用されない (なお、この値は 32 ビットシステムにも 64 ビットシステムにも適したものになっている)。 (ULONG_MAX ではなく) このデフォルト値が使われている理由については SHMALL の説明を参照。
Linux 2.2 から Linux 3.15 までは、この上限値のデフォルト値は 0x2000000 (32MB) であった。
共有メモリーセグメントの一部分だけをマッピングすることはできないので、 使用可能なセグメントの最大サイズには仮想メモリーの総量という別の上限が適用される。 例えば、i386 ではマッピング可能な最大セグメントの大きさはおおよそ 2.8GB で、 x86_64 では上限はおおよそ 127TB である。
Linux では、この上限値は /proc/sys/kernel/shmmni 経由で参照したり、変更したりできる。
プロセス当りの共有メモリーセグメントの個数の最大値 (SHMSEG) に関する実装上の制限はない。
バージョン 2.3.30 までは、Linux は 削除が予定されている共有メモリーセグメントに対して shmget() が行われると EIDRM を返していた。
IPC_PRIVATE という名前を選んだのはおそらく失敗であろう。 IPC_NEW の方がより明確にその機能を表しているだろう。
memfd_create(2), shmat(2), shmctl(2), shmdt(2), ftok(3), capabilities(7), shm_overview(7), svipc(7)
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。
2015-01-10 | Linux |