semop() - セマフォー操作

規格

標準/拡張機能 C/C++ 依存項目
XPG4
XPG4.2

Single UNIX Specification、バージョン 3
both  

Format

#define _XOPEN_SOURCE
#include <sys/sem.h>

int semop(int semid, struct sembuf *sops, size_t nsops);

機能説明

semop() 関数は、引数 semid と関連したセマフォーのセット上でセマフォー操作を自動的に実行します。 引数 sops は、sembuf データ構造の配列へのポインターです。 引数 nsops は、配列中の sembuf 構造体の数です。

構造体 sembuf は、以下のように定義されます。

    short    sem_num    0 ~ (nsems から 1 を引いた値) 内のセマフォー数
    short    sem_op     セマフォー操作
    short    sem_flg    操作フラグ

セマフォー・セットの各セマフォー (sem_num によって識別される) は、次の無名データ構造によって表されます。 すべてのセマフォーのこのデータ構造は、semop() が正常に戻ると自動的に 更新されます。

sem_op で指定された各セマフォー操作は 、semid および sem_num で指定された 対応するセマフォーで実行されます。

変数 sem_op で、次の 3 つのセマフォー操作の 1 つが指定されます。
  1. sem_op が負の整数で、呼び出しプロセスに 変更許可がある場合には、次のうちの 1 つが起こることになります。
    • semval (<sys/sem.h> を参照) が sem_op の絶対値より大きいか等しい場合、sem_op の絶対値が、semval から減算されます。
    • semval が、sem_op の絶対値より 小さく、(sem_flg および IPC_NOWAIT) が ゼロ以外の場合は、semop() が即時に戻されます。
    • semval が、sem_op の絶対値より 小さく、(sem_flg および IPC_NOWAIT) がゼロの場合には、semop() により、指定セマフォーと関連 した semncnt が増分され、次の条件のいずれかが生じるまで、呼び出しプロセスの実行は中断されます。
      • semval の値は、sem_op の絶対値 より大きいか等しくなります。 この場合は、指定セマフォーと関連した semncnt の値は減少させられ 、sem_op の絶対値は、semval から減算 されます。
      • 呼び出しプロセスが待機中の semid は、システムから削除されます。 この場合は、errno が EIDRM と等しく設定され、-1 が戻されます。
      • 呼び出しプロセスが、取得すべきシグナルを受信します。 この場合は、指定セマフォーと関連した semncnt の値は減少させられ、呼び出しプロセスにより、sigaction() で規定された方法で 実行が再開されます。
  2. sem_op が正整数で、呼び出しプロセスに変更許可がある場合には、sem_op の値が semval に追加されます。
  3. sem_op がゼロで、呼び出しプロセスに読み取り許可がある場合には、次のうちの 1 つが起こることになります。
    • semval がゼロの場合には、semop() が即時に戻されます。
    • semval がゼロ以外で、(sem_flg および IPC_NOWAIT) がゼロ以外の場合には、semop() は即時に戻ります。
    • semval がゼロ以外で、(sem_flg および IPC_NOWAIT) がゼロの場合には、semop() は、指定セマフォーと関連した semzcnt を増分し、次の条件のいずれかが生じるまで、呼び出しスレッドの実行は中断されます。
      • 指定セマフォーと関連した semzcnt の値の 減少時に、semval の値が 0 になる。
      • 呼び出しプロセスが待機中の semid は、システムから削除されます。 この場合は、errno が EIDRM と等しく設定され、-1 が戻されます。
      • 呼び出しプロセスが、取得すべきシグナルを受信します。 この場合は、指定セマフォーと関連した semzcnt の値は 減少させられ、呼び出しプロセスにより、sigaction() で規定された方法で 実行が再開されます。
      • 正常終了すると、sops により示される配列で指定された 各セマフォーの sempid の値が、呼び出しプロセスのプロセス ID と 等しく設定されます。
sem_flg には、以下で説明されて いる IPC_NOWAIT および SEM_UNDO フラグ が含まれています。
IPC_NOWAIT
この定数により、semop() は、スレッドを待ち状態にするのではなく、EAGAIN を戻します。
SEM_UNDO
semadj 調整値が、プロセスごとの各セマフォー に対し保守されているという結果になります。 sem_op 値 がゼロと等しくなく、SEM_UNDO が指定された 場合には、sem_op 値が、そのセマフォーの 現行プロセスの semadj 値から減算されます。 現行 プロセスが終了すると (exit() を参照)、semadj 値 が各セマフォーの semval に追加されます。 semctl() コマンド SETALL を使用して、すべてのプロセス の semadj 値が全部クリアされる場合があります。 このセマフォーについて semget で __IPC_BINSEM が指定されていると、Sem_UNDO フラグによりエラーが戻されます。

__IPC_BINSEM フラグを使用して作成したセマフォー・セットは、次のようになる必要があります。つまり、セマフォー操作の数は 1 でなければなりません。また、semop が +1 の場合、semval は 0 である必要があります。semop が -1 の場合、semval は 0 または 1 でなければなりません。 このオプションを使用する場合、SEM_UNDO を semop() で使用することはできません。 このフラグを使用すると、ハードウェアで PLO 命令が使用可能であれば、パフォーマンスが向上します。

戻り値

正常に実行された場合、semop() は 0 を戻します。 また、操作中のそれぞれのセマフォーごとの semid パラメーター値も、呼び出しプロセスのプロセス ID に設定されます。

正常に実行されなかった場合、semop() は -1 を戻して、errno を次のいずれかの 値に設定します。
エラー・コード
説明
E2BIG
nsops がシステム限界より大きくなっています。
EACCES
呼び出しプロセスへの操作許可は拒否されます。 sem_op が ゼロのときには、読み取りアクセスが必要です。 sem_op が ゼロでないときには、書き込みアクセスが必要です。
EAGAIN
呼び出しプロセスの中断という操作結果になる場合があるが、sem_flgIPC_NOWAIT が指定されました。
EFBIG
sem_num がゼロより小さいか、または semget() 引数 nsems で指定されたセット中 のセマフォー数より大きいか、あるいは等しくなっています。
EIDRM
呼び出し側の待機中に、semid がシステムから除去されました。
EINTR
semop() にシグナルが割り込みました。
EINVAL
引数 semid の値が、無効セマフォー ID です。 __IPC_BINSEM セマフォー・セットの場合、sem_val が 0 のときに sem_op は +1 以外の値であり、sem_val が 0 または 1 のときに sem_op は -1 です。 また、__IPC_BINSEM セマフォー・セットの場合、セマフォー操作の数は 2 以上になります。
ENOSPC
SEM_UNDO を要求する個々のプロセスで制限数を超えた可能性が あります。
ERANGE
操作により、semval または semadj が、<sys/sem.h> で定義されているシステム限界を超えてしまう可能性があります。

関連情報