kazmax - Linux で自宅サーバー

semget - システムコールの説明 - Linux コマンド集 一覧表

  1. 名前
  2. 書式
  3. 説明
  4. 返り値
  5. エラー
  6. 注意
  7. バグ
  8. 準拠
  9. 関連項目

名前

semget - セマフォ集合の識別子を取得する

書式

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semget(key_t key , int nsems , int semflg );

説明

semget ()システムコールは、引き数 key に対応するセマフォ集合 (semaphore set) の 識別子 (identifier) を返す。 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) 許可として機能する)。

新しく作成されたセマフォ集合の各セマフォの値は不定である (この点は POSIX.1-2001 に明記されている)。 Linux は他の多くの実装と同様にセマフォ値を 0 に初期化するが、 移植性を考慮したアプリケーションではこの動作を前提にすべきではない。 アプリケーションは明示的にセマフォを希望の値で初期化すべきである。

新規のセマフォ集合を作成する際、 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
key に対応するセマフォ集合は存在するが、 呼び出し元のプロセスはその集合へのアクセス許可がなく、 CAP_IPC_OWNER ケーパビリティも持っていない。
EEXIST
key に対応するセマフォ集合が存在し、 semflg には IPC_CREATIPC_EXCL が指定されていた。
EINVAL
nsems が 0 より小さいか、セマフォ集合あたりのセマフォの最大数 ( SEMMSL )より大きい。 または、 key に対応するセマフォ集合が既に存在し、 nsems がその集合のセマフォ数よりも大きい。
ENOENT
key に対応するセマフォ集合が存在せず、 semflgIPC_CREAT が指定されてもいない。
ENOMEM
セマフォ集合を作成しようとしたが、新しいデータ構造体を 作成するのに十分なメモリがシステムに存在しない。
ENOSPC
セマフォ集合を作成しようとすると、システムのセマフォ集合の 最大数 ( SEMMNI )か、システム全体のセマフォの最大数 ( SEMMNS )のいずれかを超えてしまう。

注意

IPC_PRIVATE はフラグ・フィールドに指定するものではなく、 key_t 型である。 この特別な値が key に指定されると、 semget () semflg の下位 9 ビット以外は全て無視し、 (成功した場合は) 新しいセマフォ集合を作成する。

セマフォ集合のリソースに関する制限のうち、 semget ()に影響を及ぼすものを以下に挙げる:

SEMMNI
システム全体のセマフォ集合の最大数: 方針依存 (Linux では、この制限値は /proc/sys/kernel/sem の第4フィールドに対応し、読み出しも変更もできる)。
SEMMSL
semid あたりのセマフォの最大数: 実装依存 (Linux では、この制限値は /proc/sys/kernel/sem の第1フィールドに対応し、読み出しも変更もできる)。
SEMMNS
システム全体のセマフォの最大数: 方針依存 (Linux では、この制限値は /proc/sys/kernel/sem の第2フィールドに対応し、読み出しも変更もできる)。 SEMMSL * SEMMNI より大きな値は意味を持たない。

バグ

IPC_PRIVATE という名前を選んだのはおそらく失敗であろう。 IPC_NEW の方がより明確にその機能を表しているだろう。

セマフォ集合内のセマフォは semget ()では初期化されない。 このセマフォを初期化するには、セマフォ集合に対して   semctl (2) を使って SETVALSETALL 操作を実行する必要がある。 (複数箇所からセマフォ集合の操作が行われる場面では、 誰が最初に集合を初期化すればよいか分からない。 この状況を避けるには、 semctl ()の IPC_STAT 操作で取得できるセマフォのデータ構造体の sem_otime が 0 以外になっているかをチェックすればよい。)

準拠

SVr4, POSIX.1-2001.

関連項目