SEMCTL(2) | Linux Programmer's Manual | SEMCTL(2) |
semctl - System V セマフォの制御操作を行なう
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);
semctl() は、 semid で指定された System V セマフォ集合 (semaphore set) またはセマフォ集合の semnun 番目のセマフォに対して、 cmd で指定された制御操作を行なう (集合内のセマフォの番号は 0 から始まる)。
この関数は、 cmd の値に依存して、3 個または 4 個の引数を持つ。 引数が 4 個の場合、第 4 引数の型は union semun である。 呼び出し元プログラムは、 この共用体 (union) を以下のように定義しなければならない。
union semun { int val; /* SETVAL の値 */ struct semid_ds *buf; /* IPC_STAT, IPC_SET 用のバッファー */ unsigned short *array; /* GETALL, SETALL 用の配列 */ struct seminfo *__buf; /* IPC_INFO 用のバッファー (Linux 固有) */ };
semid_ds データ構造体は <sys/sem.h> で以下のように定義されている:
struct semid_ds { struct ipc_perm sem_perm; /* 所有権と許可 */ time_t sem_otime; /* 最後の semop の時刻 */ time_t sem_ctime; /* 作成時刻/semctl() により 最後に変更が行われた時刻 */ unsigned long sem_nsems; /* 集合内のセマフォの数 */ };
The fields of the semid_ds structure are as follows:
ipc_perm 構造体は以下のように定義されている (強調されたフィールドは IPC_SET を使って設定可能である):
struct ipc_perm { key_t __key; /* semget(2) に与えられるキー */ uid_t uid; /* 所有者 (owner) の実効 UID */ gid_t gid; /* 所有者の実効 GID */ uid_t cuid; /* 作成者 (creator) の実効 UID */ gid_t cgid; /* 作成者の実効 GID */ unsigned short mode; /* 許可 */ unsigned short __seq; /* シーケンス番号 */ };
The least significant 9 bits of the mode field of the ipc_perm structure define the access permissions for the shared memory segment. The permission bits are as follows:
0400 | Read by user |
0200 | Write by user |
0040 | Read by group |
0020 | Write by group |
0004 | Read by others |
0002 | Write by others |
In effect, "write" means "alter" for a semaphore set. Bits 0100, 0010, and 0001 (the execute bits) are unused by the system.
cmd として有効な値は次の通りである。
struct seminfo { int semmap; /* セマフォマップの最大エントリー数; カーネル内では未使用 */ int semmni; /* セマフォ集合の最大数 */ int semmns; /* 全セマフォ集合中のセマフォの 最大数 */ int semmnu; /* アンドゥ構造体のシステム全体での 最大数; カーネル内では未使用 */ int semmsl; /* 一つのセマフォ集合の最大セマフォ数 */ int semopm; /* semop(2) に渡す操作の最大数 */ int semume; /* プロセスあたりのアンドゥエントリー の最大数; カーネル内では未使用 */ int semusz; /* 構造体 sem_undo のサイズ */ int semvmx; /* セマフォの最大値 */ int semaem; /* セマフォの調整 (semaphore adjustment; SEM_UNDO) のために記録される最大値 */ };
失敗した場合、 semctl() は -1 を返し、 errno にそのエラーを示す。
そうでなければシステムコールは cmd によって以下の負でない値を返す:
cmd の値がそれ以外の場合、成功すると 0 が返される。
失敗した場合は errno には以下の値のどれかが設定される:
POSIX.1-2001, POSIX.1-2008, SVr4.
POSIX.1 では semid_ds 構造体の sem_nsems フィールドは unsigned short 型を持つと規定されており、 他のほとんどのシステムでこのフィールドは unsigned short 型になっている。 Linux 2.4 以前ではそうなっていたが、 Linux 2.4 以降ではこのフィールドは unsigned long 型である。
Linux や POSIX の全てのバージョンでは、 <sys/types.h> と <sys/ipc.h> のインクルードは必要ない。しかしながら、いくつかの古い実装ではこれらのヘッダーファイルのインクルードが必要であり、 SVID でもこれらのインクルードをするように記載されている。このような古いシステムへの移植性を意図したアプリケーションではこれらのファイルをインクルードする必要があるかもしれない。
IPC_INFO, SEM_STAT, SEM_INFO 操作は ipcs(1) プログラムによって割当られた資源について情報を提供するために使用される。 将来的にはこれらは変更されるか、 /proc ファイルシステムインターフェースに移動されるかもしれない。
構造体 semid_ds 内の多くのフィールドは、 Linux 2.2 では short 型だったが、Linux 2.4 では long 型になった。 この利点を生かすには、glibc-2.1.91 以降の環境下で 再コンパイルすれば十分である。 カーネルは新しい形式の呼び出しと古い形式の呼び出しを cmd 内の IPC_64 フラグで区別する。
初期のバージョンの glibc では、 semun 共用体は <sys/sem.h> で定義されていたが、 POSIX.1 では呼び出し側がこの共用体を定義する必要がある。 この共用体が定義されていない glibc のバージョンでは、 マクロ _SEM_SEMUN_UNDEFINED が <sys/sem.h> で定義されている。
以下は semctl() コールに影響するセマフォ集合のシステム制限:
移植性を高めるための一番良い方法は、常に 4 個の引数で semctl() を呼び出すことである。
POSIX.1 defines sempid as the "process ID of [the] last operation" on a semaphore, and explicitly notes that this value is set by a successful semop(2) call, with the implication that no other interface affects the sempid value.
While some implementations conform to the behavior specified in POSIX.1, others do not. (The fault here probably lies with POSIX.1 inasmuch as it likely failed to capture the full range of existing implementation behaviors.) Various other implementations also update sempid for the other operations that update the value of a semaphore: the SETVAL and SETALL operations, as well as the semaphore adjustments performed on process termination as a consequence of the use of the SEM_UNDO flag (see semop(2)).
Linux also updates sempid for SETVAL operations and semaphore adjustments. However, somewhat inconsistently, up to and including Linux 4.5, the kernel did not update sempid for SETALL operations. This was rectified in Linux 4.6.
shmop(2) 参照。
ipc(2), semget(2), semop(2), capabilities(7), sem_overview(7), sysvipc(7)
この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。
2020-12-21 | Linux |