SHMCTL(2) | Linux Programmer's Manual | SHMCTL(2) |
shmctl - System V 共有メモリー (shared memory) を制御する
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmctl() は、識別子が shmid の System V 共有メモリーセグメントに対して cmd で指示した制御命令を実行する。
buf 引き数は、 shmid_ds 構造体へのポインターである。 この構造体は <sys/shm.h> で以下のように定義されている
struct shmid_ds {
struct ipc_perm shm_perm; /* 所有権と許可 */
size_t shm_segsz; /* セグメントのサイズ (バイト) */
time_t shm_atime; /* 最後の付加 (attach) の時刻 */
time_t shm_dtime; /* 最後の分離 (detach) の時刻 */
time_t shm_ctime; /* 最後に変更が行われた時刻 */
pid_t shm_cpid; /* 作成者 (creator) の PID */
pid_t shm_lpid; /* 最後の shmat(2)/shmdt(2) の PID */
shmatt_t shm_nattch; /* 現在付加されている数 */
... };
ipc_perm 構造体は以下のように定義されている (強調されたフィールドは IPC_SET を使って設定可能である):
struct ipc_perm {
key_t __key; /* shmget(2) に与えられるキー */
uid_t uid; /* 所有者の実効 UID */
gid_t gid; /* 所有者の実効 GID */
uid_t cuid; /* 作成者の実効 UID */
gid_t cgid; /* 作成者の実効 GID */
unsigned short mode; /* 許可 + SHM_DEST と
SHM_LOCKED フラグ */
unsigned short __seq; /* シーケンス番号 */ };
cmd
として有効な値は以下の通り:
設定 shmmni, shmmax, shmall は /proc にある同じ名前のファイル経由で変更可能である。 詳しくは proc(5) を参照。
struct shminfo {
unsigned long shmmax; /* 最大セグメントサイズ */
unsigned long shmmin; /* 最小セグメントサイズ。
常に 1 */
unsigned long shmmni; /* 最大セグメント数 */
unsigned long shmseg; /* プロセスが付加できる
セグメントの最大数。
カーネル内では未使用 */
unsigned long shmall; /* 共有メモリーの最大ページ数。
システム全体での値 */ };
struct shm_info {
int used_ids; /* 現在存在するセグメント数 */
unsigned long shm_tot; /* 共有メモリーのページ総数 */
unsigned long shm_rss; /* メモリー上にある (スワップされて
いない) 共有メモリーページ数 */
unsigned long shm_swp; /* スワップされている共有メモリー
ページ数 */
unsigned long swap_attempts;
/* Linux 2.4 以降では未使用 */
unsigned long swap_successes;
/* Linux 2.4 以降では未使用 */ };
呼び出し元は、cmd
に以下の値を指定することで、共有メモリーセグメントが
スワップされることを防止したり、許可したりできる:
2.6.10 より前のカーネルでは、特権プロセスだけが SHM_LOCK と SHM_UNLOCK を利用することができた。 2.6.10 以降のカーネルでは、非特権プロセスであっても次の条件を満たせば これらの操作を利用することができる。その条件とは、プロセスの実効 UID がそのセグメントの所有者もしくは作成者の UID と一致し、 (SHM_LOCK の場合には) ロックするメモリーの合計が RLIMIT_MEMLOCK リソース上限 (setrlimit(2) 参照) の範囲内に入っていることである。
IPC_INFO と SHM_INFO 操作は、成功すると、全ての共有メモリーセグメントに関する情報を 管理しているカーネルの内部配列の使用中エントリーのインデックスの うち最大値を返す (この情報は、システムの全ての共有メモリーセグメントに関する情報を 取得するために、 SHM_STAT 操作を繰り返し実行する際に使用できる)。 SHM_STAT 操作は、成功すると、 shmid で指定されたインデックスを持つ共有メモリーセグメントの識別子を返す。 他の操作は、成功の場合 0 を返す。
エラーの場合は -1 を返し、 errno を適切に設定する。
または (2.6.9 より前のカーネルで) SHM_LOCK または SHM_UNLOCK が指定されているが、プロセスが特権を持たない (Linux では CAP_IPC_LOCK ケーパビリティを持たない)。 (Linux 2.6.9 以降では、 RLIMIT_MEMLOCK が 0 で呼び出し元が特権を持たない場合にも、このエラーが起こる。)
SVr4, POSIX.1-2001.
Linux や POSIX の全てのバージョンでは、 <sys/types.h> と <sys/ipc.h> のインクルードは必要ない。しかしながら、いくつかの古い実装ではこれらのヘッダーファイルのインクルードが必要であり、 SVID でもこれらのインクルードをするように記載されている。このような古いシステムへの移植性を意図したアプリケーションではこれらのファイルをインクルードする必要があるかもしれない。
IPC_INFO, SHM_STAT, SHM_INFO 操作は、 ipcs(1) プログラムで割り当て済の資源に関する情報を提供するために 使用されている。将来、これらの操作は変更されたり、 /proc ファイルシステムのインターフェースに移動されるかもしれない。
Linux では、 shmctl(IPC_RMID) を使ってすでに削除マークがつけられている共有メモリーセグメントを あるプロセスが付加 (attach) (shmat(2)) することを許可している。 この機能は他の UNIX の実装では利用できない。 移植性を考慮したアプリケーションではこれに依存しないようにすべきである。
構造体 shmid_ds 内の多くのフィールドは、 Linux 2.2 では short 型だったが、Linux 2.4 では long 型になった。 この利点を生かすには、glibc-2.1.91 以降の環境下で 再コンパイルすれば十分である。 カーネルは新しい形式の呼び出しと古い形式の呼び出しを cmd 内の IPC_64 フラグで区別する。
mlock(2), setrlimit(2), shmget(2), shmop(2), capabilities(7), shm_overview(7), svipc(7)
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。
2014-02-07 | Linux |