Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       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 の場合、もしくは semflgIPC_CREAT が指定されていて、 key に対応するセマフォ集合
       が存在しない場合、 nsems 個のセマフォからなる新しい集合が作成される。

       semflgIPC_CREATIPC_EXCL  の両方が指定された場合、  key  に対応するセマフォ集合が既に存在すると、
       semget()  は失敗し、 errnoEEXIST が設定される (これは 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.cuidsem_perm.uid に、呼び出し元のプロセスの実効 (effective) ユーザー ID を設定する。

       • sem_perm.cgidsem_perm.gid に、呼び出し元のプロセスの実効 (effective) グループ ID を設定する。

       • sem_perm.mode の下位 9 ビットに semflg の下位 9 ビットを設定する。

       • sem_nsemsnsems の値を設定する。

       • 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 semflgIPC_CREATIPC_EXCL が指定されたが、 key に対応するセマフォ集合はすでに存在する。

       EINVAL nsems が 0 より小さいか、 セマフォ集合あたりのセマフォの最大数 (SEMMSL) より大きい。

       EINVAL key に対応するセマフォ集合が既に存在するが、 nsems がその集合のセマフォ数よりも大きい。

       ENOENT key に対応するセマフォ集合が存在せず、 semflgIPC_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) の SETVALSETALL 操作を使って初期化することができる。 複数箇所からセマフォ集合の操作が行われ
       る場面では、 誰が最初に集合を初期化すればよいか分からない。 この状況を避けるには、 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
              フィールドであり、読み出しも変更もできる)。 システム全体のセマフォ数には、 SEMMSLSEMMNI の積と
              いう上限もある。

バグ

       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/ に書かれている。