Provided by: manpages-ja-dev_0.5.0.0.20140515+dfsg-2_all
名前
shmat, shmdt - System V 共有メモリ (shared memory) の操作
書式
#include <sys/types.h> #include <sys/shm.h> void *shmat(int shmid, const void *shmaddr, int shmflg); int shmdt(const void *shmaddr);
説明
shmat() は shmid で指定された System V 共有メモリ・セグメント (shared memory segment) を コールしたプロセスのアドレス空間に付加 (attach) する。 付加するアドレスは shmaddr に以下の どれかの形式で指定する: shmaddr が NULL ならば、システムはセグメントを付加するための 適切な (使用されていない) ア ドレスを選択する。 shmaddr が NULL でなく SHM_RND が shmflg に指定されている場合は、 shmaddr を SHMLBA の倍数 へと切り捨てた (rounding down) のと等しいアドレスへ付加する。 その他の場合は shmaddr は付 加を行なうアドレスで、ページ境界を指している必要がある。 SHM_RDONLY が shmflg に指定されていた場合は、 セグメントは読み込み専用に付加され、プロセス はそのセグメントへの 読み込み許可を持たなければならない。 そうでなければそのセグメントは読 み込みと書き込みのために付加され、 プロセスはそのセグメントに読み込みと書き込みの許可を持 つ必要がある。 書き込み専用の共有メモリ・セグメントという概念は存在しない。 (Linux 特有の) SHM_REMAP フラグが shmflg に指定された場合は、 セグメントのマッピングを既 存のマッピングに置き換える。 マッピングの範囲は、 shmaddr から始まりセグメントのサイズ分だ けある (通常 EINVAL エラーは、このアドレス範囲にマッピングが既に存在するために起る)。 この フラグを指定する場合は、 shmaddr が NULL であってはならない。 呼び出したプロセスの brk(2) の値は付加によって変化しない。 そのセグメントはプロセスが終了 (exit) したら自動的に分離 (detach) される。 同じセグメントをプロセスのアドレス空間に、読み 込み専用および読み書き両用 として付加でき、また複数回付加することもできる。 成功した shmat() コールは共有メモリ・セグメントに関連する shmid_ds 構造体 (shmctl(2) を 参照) のメンバーを以下のように更新する: shm_atime には現在の時刻を設定する。 shm_lpid には呼び出したプロセスのプロセス ID が設定される。 shm_nattch を 1 増加させる。 shmdt() は呼び出したプロセスのアドレス空間から shmaddr で指定されたアドレスに配置された共 有メモリ・セグメントを分離 (detach) する。 分離する共有メモリ・セグメントは、現在 shmaddr に付加されているものでなければならない。 shmaddr は、それを付加した時に shmat() が返した 値に等しくなければならない。 成功した shmdt() コールはその共有メモリ・セグメントに関連する shmid_ds 構造体のメンバーを 以下のように更新する: shm_dtime には現在の時刻が設定される。 shm_lpid には呼び出したプロセスのプロセス ID が設定される。 shm_nattch を 1 減少させる。 もし 0 になり、削除マークがあった場合は そのセグメント は削除される。 fork(2) した後、子プロセスは付加された共有メモリ・セグメントを継承する。 exec(2) した後、全ての付加された共有メモリ・セグメントはプロセスから分離される。 exit(2) において、全ての付加された共有メモリ・セグメントはプロセスから分離される。
返り値
shmat() は、成功した場合、 付加された共有メモリ・セグメントのアドレスを返す。 エラーの場 合、 (void *) -1 を返し、 errno にエラーの原因を示す値を設定する。 shmdt() は、成功すると 0 を返す。 エラーの場合、-1 を返し、 errno にエラーの原因を示す値 を設定する。
エラー
shmat() が失敗した場合、 errno に以下の値のどれかを設定して返す: EACCES 呼び出したプロセスに要求された種類の付加に必要な許可がなく、 CAP_IPC_OWNER ケーパビ リティ (capability) がない。 EIDRM shmid が削除 (remove) された識別子 (identifier) を指している。 EINVAL shmid の値が不正である。 shmaddr の値が境界違反 (unaligned) (つまり、ページ境界に 合っておらず、 SHM_RND が指定されていない) または が不正である。 shmaddr へのセグメ ントの付加に失敗した。 または SHM_REMAP が指定されているが、 shmaddr が NULL であっ た。 ENOMEM ディスクリプター (descriptor) やページ・テーブルのためのメモリを 割り当てることがで きない。 shmdt() が失敗した場合、 EINVAL は以下のようにセットされる: EINVAL shmaddr に付加された共有メモリ・セグメントが存在しない。 もしくは、 shmaddr がペー ジ境界に合っていない。
準拠
SVr4, POSIX.1-2001. SVID 3 で (たぶんそれより前だと思うが) shmaddr 引き数の型は char * から const void * に、shmat() の返り値の型は char * から void * に変更された (Linux では libc4 と libc5 のプ ロトタイプは char * であり、glibc2 のプロトタイプは void * である)。
注意
共有メモリセグメントを付加する場合の移植性の高い方法としては、 shmaddr を NULL にして shmat() を使用するのがよい。 このような方法で付加される共有メモリセグメントは、 プロセス が異なれば別のアドレスに付加される、という点に注意すること。 よって共有メモリ内で管理され るポインタは、 絶対アドレスではなく、 (一般的にはセグメントの開始アドレスからの) 相対アド レスで作成するべきである。 Linux では共有メモリセグメントに既に削除マークが付けられていても、 その共有メモリセグメン トを付加することができる。 しかし POSIX.1-2001 ではこのような動作を指定しておらず、 他の多 くの実装もこれをサポートしていない。 以下のシステム・パラメーターは、 shmat() に影響する: SHMLBA セグメントの境界アドレスの最小倍数。ページ境界に合ってなければならない。 現在の実装 では SHMLBA の値は PAGE_SIZE である。 現在の実装では、プロセスごとの 共有メモリ・セグメントの最大数 (SHMSEG) に関する実装依存の 制限はない。
関連項目
brk(2), mmap(2), shmctl(2), shmget(2), capabilities(7), shm_overview(7), svipc(7)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.65 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。