SHMGET(2)

名前
shmget - 共有メモリ・セグメント(shared memory segment)を割り当てる

書式
#include <sys/ipc.h>

#include <sys/shm.h>

int shmget(key_t key, int size, int shmflg);

説明
shmget() は key 引き数の値に関連する共有メモリ・セグメントの識別子(identifier)を 返す。もし key の値が IPC_PRIVATE の場合は新しい共有メモリ・セグメントを作成する。 key の値が IPC_PRIVATE でなくても、 key に共有メモリ・セグメントが割り当てられておらず、 shmflg に IPC_CREAT が指定されている( shmflg&IPC_CREAT がゼロでない)場合にも 新しい共有メモリ・セグメントを作成する。 新しく作成される共有メモリ・セグメントは引き数 size を PAGE_SIZE の倍数へと切り上げた(round up)大きさとなる。

shmflg は以下の内容から構成される:

IPC_CREAT
    新しいセグメントを作成する。このフラグが使用されなかったならば、 shmget() は key に関連するセグメントを見つけて、ユーザーがそのセグメント に関連する shmid を受けとる許可があることをチェックし、その セグメントが破壊(destruction)マークが付いていないことを保証する。

IPC_EXCL
    は IPC_CREAT と共に使用し、セグメントが存在した場合には 失敗することを保証する。

mode_flags (lowest 9 bits)
    は所有者(owner)、グループ(group)、他人(world)への許可を指定する。 今のところ、実行(execute)許可はシステムによって使用されていない。

もし新しいセグメントが作成された場合、 shmflg からのアクセス許可はセグメントを定義する shmid_ds 構造体の shm_perm メンバーへとコピーされる。shmid_ds 構造体は:

struct shmid_ds {
	struct	ipc_perm shm_perm;	/* operation perms */
	int	shm_segsz;		/* size of segment (bytes) */
	time_t	shm_atime;		/* last attach time */
	time_t	shm_dtime;		/* last detach time */
	time_t	shm_ctime;		/* last change time */
	unsigned short	shm_cpid;	/* pid of creator */
	unsigned short	shm_lpid;	/* pid of last operator */
	short	shm_nattch;		/* no. of current attaches */
};

struct ipc_perm
{
  key_t  key;
  ushort uid;   /* owner euid and egid */
  ushort gid;
  ushort cuid;  /* creator euid and egid */
  ushort cgid;
  ushort mode;  /* lower 9 bits of shmflg */
  ushort seq;   /* sequence number */
};

さらに、作成時に、 このシステム・コールはシステムの共有メモリ・セグメントのデータ構造体 shmid_ds を以下のように初期化する。

    shm_perm.cuid と shm_perm.uid には呼び出したプロセスの実効(effective)ユーザーID が設定される。

    shm_perm.cgid と shm_perm.gid には呼び出したプロセスの実効(effective)グループID が設定される。

    shm_perm.mode の下位 9ビットには shmflg の下位 9ビットが設定される。

    shm_segsz には size の値が設定される。

    shm_lpid, shm_nattch, shm_atime と shm_dtime には 0 が設定される。

    shm_ctime には現在時刻が設定される。

既に共有メモリ・セグメントが存在した場合は、アクセス・許可が確認され、 それが破壊マークをされていないかをチェックする。

システム・コール

fork()
    fork() の後に、子プロセスは付加(attach)された共有メモリ・セグメントを継承する。

exec()
    exec() の後に、 全ての付加された共有メモリ・セグメントは分離(detach)される。 (破壊はされない)。

exit()
    exit() において、 全ての付加された共有メモリ・セグメントは分離される。(破壊はされない)。

返り値
成功した場合は有効なセグメント識別子(identifier) shmid を返す、エラーの場合は -1 を返す。

エラー
失敗した場合は errno が以下のどれかに設定される:

EINVAL
    はSHMMIN > size や size > SHMMAX や size がセグメントのサイズより大きい場合に返される。

EEXIST
    は IPC_CREAT | IPC_EXCL が指定されており、セグメントが存在する場合に返される。

EIDRM
    はセグメントに破壊(destroy)マークがある場合や既に削除されている場合に返される。

ENOSPC
    は全ての可能な共有メモリ ID (SHMMNI) を使い果たしていた場合や、要求された size のセグメントの割り当てが システム全体の共有メモリの制限 (SHMALL) を超えている場合に返される。

ENOENT
    は与えられた key に対応するセグメントが存在せず、 IPC_CREAT が指定されていない場合に返される。

EACCES
    はユーザーがその共有メモリ・セグメントにアクセス許可を持たない場合に 返される。

ENOMEM
    セグメントの作成の作業用のためのメモリを割り当てることができな かった場合に返される。

注意
IPC_PRIVATE はフラグではなく key_t の種類である。 この特別な値が key に使用された場合は、システム・コールは shmflg の下位 9ビットを除いた全てを無視して (成功した場合は)新しい共有メモリ・セグメントを作成する。

以下は shmget コールに影響する共有メモリ・セグメント資源の制限である:

SHMALL
    システム全体の共有メモリ・ページの最大数: 方針依存。

SHMMAX
    共有メモリ・セグメントのバイト単位の大きさの上限: 実装依存 (現在は 4M)。

SHMMIN
    共有メモリ・セグメントのバイト単位の大きさの下限: 実装依存 (現在は 1バイトだが、実効的な最小サイズは PAGE_SIZE である。)

SHMMNI
    システム全体の共有メモリーの数の上限: 実装依存(現在は 4096)

この実装ではプロセス当りの共有メモリ・セグメントの 使用に特定の上限 (SHMSEG) は存在しない。

バグ
IPC_PRIVATE を使用したとしても、割り当てられた共有メモリ・セグメントを 他のプロセスがアクセスすることを妨げることはできない。

ファイルと同様に、今のところプロセスの共有メモリ・セグメントへの 排他的なアクセスを保証する固有の方法は存在しない。 IPC_CREAT と IPC_EXCL の両方を shmflg に設定することは(成功した場合は) 新しい共有メモリ・セグメントが作成されることのみを保証し、 そのセグメントへの排他的なアクセスを保証するものではない。

準拠
SVr4, SVID. SVr4 には他に EEXIST エラー状態の記述がある。 SVr4 と SVID には EIDRM についての記述はない。

関連項目
ftok(3), ipc(5), shmctl(2), shmat(2), shmdt(2).