書式
#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 は以下の内容から構成される:
- IPC_CREAT
- 新しいセグメントを作成する。このフラグが指定されなかった場合、 shmget() は key に対応するセグメントを探し、 ユーザがそのセグメントにアクセスする許可があるかどうかをチェックする。
- IPC_EXCL
- IPC_CREAT と共に使用し、セグメントが既に存在した場合には 失敗することを保証する。
- mode_flags
- (下位 9 ビット) 所有者、グループ、他人 (world) への許可を指定する。 これらのビットは open(2) の mode 引き数と同じ形式で同じ意味を持つ。 今のところ、システムは実行 (execute) 許可を参照しない。
- SHM_HUGETLB (Linux 2.6 以降)
- "ヒュージページ (huge page)" を使うセグメントを割り当てる。詳細な情報は、Linux カーネルソースのファイル Documentation/vm/hugetlbpage.txt を参照。
- SHM_NORESERVE (Linux 2.6.15 以降)
- このフラグは、 mmap(2) の MAP_NORESERVE フラグと同じ役割を果たす。 このセグメントに対するスワップ空間の予約を行わない。 スワップ空間を予約した場合は、そのセグメントの変更が必ず成功することが 保証される。スワップ空間の予約を行わなかった場合は、物理メモリに空きが ないと書き込み時に SIGSEGV を受け取る可能性がある。 proc(5) にある /proc/sys/vm/overcommit_memory ファイルに関する議論も参照のこと。
共有メモリ・セグメントが新たに作成される際、 共有メモリ・セグメントの内容は 0 で初期化され、 関連情報を保持するデータ構造体 shmid_ds は以下のように初期化される。
- shm_perm.cuid と shm_perm.uid に呼び出し元プロセスの実効 (effective) ユーザーID を設定する。
- shm_perm.cgid と shm_perm.gid に呼び出し元プロセスの実効グループID を設定する。
- shm_perm.mode の下位 9 ビットに shmflg の下位 9 ビットを設定する。
- shm_segsz に size の値を設定する。
- shm_lpid, shm_nattch, shm_atime, shm_dtime に 0 を設定する。
- shm_ctime に現在の時刻を設定する。
共有メモリ・セグメントが既に存在する場合、アクセス許可の検査と、 破壊 (destruction) マークがつけられていないかのチェックが行われる。
返り値
成功の場合、有効な共有メモリ・セグメントの識別子が返される。 エラーの場合、 -1 が返り、 error にエラーを示す値が設定される。エラー
失敗した場合は errno が以下のどれかに設定される:- EACCES
- ユーザーはその共有メモリ・セグメントへのアクセス許可を持たず、 CAP_IPC_OWNER ケーパビリティも持っていない。
- EEXIST
- IPC_CREAT | IPC_EXCL が指定されていたが、そのセグメントが既に存在する。
- EINVAL
- 新しいセグメントを作成しようとした際に size < SHMMIN または size > SHMMAX であった。 もしくは、指定されたキーに対応するセグメントが既に存在して、新しい セグメントを作成しようとはしなかったが、size が存在するセグメントの サイズよりも大きかった。
- ENFILE
- システム全体でオープンされているファイルの総数が上限に達した。
- ENOENT
- 指定された key に対応するセグメントが存在せず、 IPC_CREAT も指定されていなかった。
- ENOMEM
- セグメントの管理情報 (overhead) に割り当てるメモリがなかった。
- ENOSPC
- システム全体の共有メモリ・セグメント数の制限 (SHMMNI) に達した、または要求された size のセグメントの割り当てが システム全体の共有メモリサイズの制限 (SHMALL) を超過した。
- EPERM
- SHM_HUGETLB フラグが指定されたが、呼び出し元には権限がなかった (CAP_IPC_LOCK ケーパビリティを持っていなかった)。
準拠
SVr4, POSIX.1-2001.SHM_HUGETLB は Linux での拡張であり、移植性はない。
注意
Linux や POSIX の全てのバージョンでは、 <sys/types.h> と <sys/ipc.h> のインクルードは必要ない。しかしながら、いくつかの古い実装ではこれらのヘッダファイルのインクルードが必要であり、 SVID でもこれらのインクルードをするように記載されている。このような古いシステムへの移植性を意図したアプリケーションではこれらのファイルをインクルードする必要があるかもしれない。IPC_PRIVATE はフラグではなく key_t 型である。 この特別な値が key に使用された場合は、 shmget() は shmflg の下位 9 ビットを除いた全てを無視し、 (成功すれば) 新しい共有メモリ・セグメントを作成する。
shmget() コールに影響する共有メモリ・セグメント資源の制限は以下の通りである:
- SHMALL
-
システム全体の共有メモリ・ページの最大数。 Linux 2.2 以降では、この上限値のデフォルトは以下である。
SHMMAX / PAGE_SIZE * (SHMMNI / 16)4kB ページサイズと仮定すると、 (Linux 2.4 以降では) この式の結果は 2^20 (2,097,152) になる。
Linux では、この上限値は /proc/sys/kernel/shmall 経由で参照したり、変更したりできる。
- SHMMAX
-
共有メモリ・セグメントの最大バイト数。 Linux 2.2 以降では、 この上限値のデフォルトは 0x2000000 (32MB) である。
Linux では、この上限値は /proc/sys/kernel/shmmax 経由で参照したり、変更したりできる。
- SHMMIN
- 共有メモリ・セグメントのバイト単位の大きさの下限: 実装依存 (現在は 1 バイトだが、実質的な最小サイズは PAGE_SIZE である)。
- SHMMNI
-
システム全体の共有メモリ・セグメントの最大数。 この上限値のデフォルトは、 Linux 2.2 以降では 128、 Linux 2.4 以降で 4096
である。
Linux では、この上限値は /proc/sys/kernel/shmmni 経由で参照したり、変更したりできる。
プロセス当りの共有メモリ・セグメントの個数の最大値 (SHMSEG) に関する実装上の制限はない。
Linux での注意
バージョン 2.3.30 までは、Linux は 削除が予定されている共有メモリ・セグメントに対して shmget() が行われると EIDRM を返していた。バグ
IPC_PRIVATE という名前を選んだのはおそらく失敗であろう。 IPC_NEW の方がより明確にその機能を表しているだろう。この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.65 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。