semop() - セマフォー操作

標準

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

XPG4
XPG4.2
Single UNIX Specification、バージョン 3

両方  

形式

#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 が増分され、呼び出しプロセスの 実行が、次の条件の 1 つが起こるまで中断されます。
      • 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) が 0 の場合には、semop() は、指定セマフォーと関連した semzcnt を増分し、呼び出しスレッドの 実行は、次の条件の 1 つが起こるまで中断されます。
      • 指定セマフォーと関連した 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 です。また、セマフォー操作の数は 2 以上になります。
ENOSPC
SEM_UNDO を要求する個々のプロセスで制限数を超えた可能性が あります。
ERANGE
操作により、semval または semadj が、<sys/sem.h> で定義されているシステム限界を超えてしまう可能性があります。