Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all
名前
semget - System V セマフォ集合の識別子を取得する
書式
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semget(key_t key, int nsems, int semflg);
説明
The semget() system call returns the System V semaphore set identifier associated with the argument key. It may be used either to obtain the identifier of a previously created semaphore set (when semflg is zero and key does not have the value IPC_PRIVATE), or to create a new set. key の値が IPC_PRIVATE の場合、もしくは semflg に IPC_CREAT が指定されていて、 key に対応 するセマフォ集合が存在しない場合、 nsems 個のセマフォからなる新しい集合が作成される。 semflg に IPC_CREAT と IPC_EXCL の両方が指定された場合、 key に対応するセマフォ集合が既に 存在すると、 semget() は失敗し、 errno に EEXIST が設定される (これは open(2) に O_CREAT | O_EXCL が指定された場合の動作と同じである)。 セマフォ集合作成時に、引数 semflg の下位 9 ビットは、そのセマフォ集合の (所有者 (owner)、グループ (group)、 他人 (others) に対する) アクセス許可の定義として使用される。 これらのビットは open(2) の引数 mode と同じ形式で同じ意味である (但し、実行 (execute) 許 可はセマフォでは意味を持たず、 書き込み (write) 許可はセマフォ値の変更 (alter) 許可として 機能する)。 新規のセマフォ集合を作成する際、 semget() はセマフォ集合の情報を保持するデータ構造体 semid_ds を次のように初期化する (semid_ds については semctl(2) を参照): • sem_perm.cuid と sem_perm.uid に、呼び出し元のプロセスの実効 (effective) ユーザー ID を 設定する。 • sem_perm.cgid と sem_perm.gid に、呼び出し元のプロセスの実効 (effective) グループ ID を 設定する。 • sem_perm.mode の下位 9 ビットに semflg の下位 9 ビットを設定する。 • sem_nsems に nsems の値を設定する。 • sem_otime に 0 を設定する。 • sem_ctime に現在の時刻を設定する。 セマフォ集合の作成を行わない場合は、引数 nsems に (don't care を意味する) 0 を指定してもよ い。 そうでない場合は、 nsems は 0 より大きい値でなければならず、セマフォ集合あたりのセマ フォの最大数 (SEMMSL) 以下でなければならない。 セマフォ集合が既に存在した場合は、アクセス許可の検査が行われる。
返り値
成功した場合、セマフォ集合の識別子 (非負の整数) が返り値となる。 失敗した場合は -1 が返さ れ、 errno にエラーを示す値が設定される。
エラー
失敗した場合は errno には以下の値のどれかが設定される: EACCES A semaphore set exists for key, but the calling process does not have permission to access the set, and does not have the CAP_IPC_OWNER capability in the user namespace that governs its IPC namespace. EEXIST semflg に IPC_CREAT と IPC_EXCL が指定されたが、 key に対応するセマフォ集合はすでに 存在する。 EINVAL nsems が 0 より小さいか、 セマフォ集合あたりのセマフォの最大数 (SEMMSL) より大き い。 EINVAL key に対応するセマフォ集合が既に存在するが、 nsems がその集合のセマフォ数よりも大き い。 ENOENT key に対応するセマフォ集合が存在せず、 semflg に IPC_CREAT が指定されてもいない。 ENOMEM セマフォ集合を作成しようとしたが、新しいデータ構造体を 作成するのに十分なメモリーが システムに存在しない。 ENOSPC セマフォ集合を作成しようとすると、システムのセマフォ集合の 最大数 (SEMMNI) か、シ ステム全体のセマフォの最大数 (SEMMNS) のいずれかを超えてしまう。
準拠
SVr4, POSIX.1-2001.
注意
Linux や POSIX の全てのバージョンでは、 <sys/types.h> と <sys/ipc.h> のインクルードは必要 ない。しかしながら、いくつかの古い実装ではこれらのヘッダーファイルのインクルードが必要であ り、 SVID でもこれらのインクルードをするように記載されている。このような古いシステムへの移 植性を意図したアプリケーションではこれらのファイルをインクルードする必要があるかもしれな い。 IPC_PRIVATE はフラグフィールドに指定するものではなく、 key_t 型である。 この特別な値が key に指定されると、 semget() semflg の下位 9 ビット以外は全て無視し、 (成功した場合は) 新し いセマフォ集合を作成する。 セマフォの初期化 新しく作成されたセマフォ集合の各セマフォの値は不定である。 (この点は POSIX.1-2001 と POSIX.1-2008 に明記されている。ただし、POSIX.1-2008 では POSIX の将来のバージョンではセマ フォを 0 に初期化するように実装に要求する可能性が注記されている。) Linux は他の多くの実装 と同様にセマフォ値を 0 に初期化するが、 移植性を考慮したアプリケーションではこの動作を前提 にすべきではない。 アプリケーションは明示的にセマフォを希望の値で初期化すべきである。 semctl(2) の SETVAL か SETALL 操作を使って初期化することができる。 複数箇所からセマフォ集 合の操作が行われる場面では、 誰が最初に集合を初期化すればよいか分からない。 この状況を避け るには、 semctl(2) の IPC_STAT 操作で取得できるセマフォのデータ構造体の sem_otime が 0 以 外になっているかをチェックすればよい。 セマフォの上限 セマフォ集合のリソースに関する上限のうち、 semget() に影響を及ぼすものを以下に挙げる: SEMMNI System-wide limit on the number of semaphore sets. On Linux systems before version 3.19, the default value for this limit was 128. Since Linux 3.19, the default value is 32,000. On Linux, this limit can be read and modified via the fourth field of /proc/sys/kernel/sem. SEMMSL Maximum number of semaphores per semaphore ID. On Linux systems before version 3.19, the default value for this limit was 250. Since Linux 3.19, the default value is 32,000. On Linux, this limit can be read and modified via the first field of /proc/sys/kernel/sem. SEMMNS システム全体のセマフォ数の上限値: 方針依存 (Linux では、この上限値は /proc/sys/kernel/sem の第 2 フィールドであり、読み出しも変更もできる)。 システム全 体のセマフォ数には、 SEMMSL と SEMMNI の積という上限もある。
バグ
IPC_PRIVATE という名前を選んだのはおそらく失敗であろう。 IPC_NEW の方がより明確にその機能 を表しているだろう。
例
The program shown below uses semget() to create a new semaphore set or retrieve the ID of an existing set. It generates the key for semget() using ftok(3). The first two command-line arguments are used as the pathname and proj_id arguments for ftok(3). The third command-line argument is an integer that specifies the nsems argument for semget(). Command-line options can be used to specify the IPC_CREAT (-c) and IPC_EXCL (-x) flags for the call to semget(). The usage of this program is demonstrated below. We first create two files that will be used to generate keys using ftok(3), create two semaphore sets using those files, and then list the sets using ipcs(1): $ touch mykey mykey2 $ ./t_semget -c mykey p 1 ID = 9 $ ./t_semget -c mykey2 p 2 ID = 10 $ ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems 0x7004136d 9 mtk 600 1 0x70041368 10 mtk 600 2 Next, we demonstrate that when semctl(2) is given the same key (as generated by the same arguments to ftok(3)), it returns the ID of the already existing semaphore set: $ ./t_semget -c mykey p 1 ID = 9 Finally, we demonstrate the kind of collision that can occur when ftok(3) is given different pathname arguments that have the same inode number: $ ln mykey link $ ls -i1 link mykey 2233197 link 2233197 mykey $ ./t_semget link p 1 # Generates same key as 'mykey' ID = 9 プログラムのソース /* t_semget.c Licensed under GNU General Public License v2 or later. */ #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> static void usage(const char *pname) { fprintf(stderr, "Usage: %s [-cx] pathname proj-id num-sems\n", pname); fprintf(stderr, " -c Use IPC_CREAT flag\n"); fprintf(stderr, " -x Use IPC_EXCL flag\n"); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { int semid, nsems, flags, opt; key_t key; flags = 0; while ((opt = getopt(argc, argv, "cx")) != -1) { switch (opt) { case 'c': flags |= IPC_CREAT; break; case 'x': flags |= IPC_EXCL; break; default: usage(argv[0]); } } if (argc != optind + 3) usage(argv[0]); key = ftok(argv[optind], argv[optind + 1][0]); if (key == -1) { perror("ftok"); exit(EXIT_FAILURE); } nsems = atoi(argv[optind + 2]); semid = semget(key, nsems, flags | 0600); if (semid == -1) { perror("semget"); exit(EXIT_FAILURE); } printf("ID = %d\n", semid); exit(EXIT_SUCCESS); }
関連項目
semctl(2), semop(2), ftok(3), capabilities(7), sem_overview(7), sysvipc(7)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの 説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。