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