semop() - セマフォー操作
標準
| 標準/拡張機能 | C/C++ | 依存項目 |
|---|---|---|
XPG4 |
両方 |
形式
#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() が正常に戻ると自動的に
更新されます。
| unsigned short int | semval | セマフォー値 |
| pid_t | sempid | 最終操作のプロセス ID |
| unsigned sort int | semcnt | semval が現行値より大きくなるのを待っているプロセスの数 |
| unsigned short int | semzcnt | semval がゼロになるのを待っているプロセスの数 |
sem_op で指定された各セマフォー操作は 、semid および sem_num で指定された 対応するセマフォーで実行されます。
変数 sem_op で、次の 3 つのセマフォー操作の 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() で規定された方法で 実行が再開されます。
- sem_op が正整数で、呼び出しプロセスに変更許可がある場合には、sem_op の値が semval に追加されます。
- 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_flg の IPC_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> で定義されているシステム限界を超えてしまう可能性があります。