SEMOP(2)

名称
semop - セマフォ集合に対する不可分な操作の配列

ライブラリ
libc

書式
<sys/types.h> <sys/ipc.h> <sys/sem.h> int semop(int semid, struct sembuf *array, size_t nops)

解説
semop() システムコールは、 semid が示すセマフォ集合に対して、 array が示す操作の配列を不可分に実行します。 array の長さは nops で示します。 各操作は struct sembuf 内にエンコードされており、 struct sembuf は次のように定義されます:

    struct sembuf {
            u_short sem_num;        /* セマフォ番号 */
            short   sem_op;         /* セマフォ操作 */
            short   sem_flg;        /* 操作フラグ */
    };

array 内の各要素に関し、 sem_op と sem_flg は、集合内のセマフォ番号 sem_num に対して実行される操作を決定します。 指定した操作の動作を変更するために、 SEM_UNDO と IPC_NOWAIT の値の論理和 ( OR ) を取って sem_flg メンバに入れることが可能です。

実行される操作は次のように sem_op の値に依存します:

•   sem_op が正であり、プロセスが別のパーミッションを持っている場合、セマフォの値を sem_op の値だけ増加させます。 SEM_UNDO を指定した場合、セマフォの終了時調整値を sem_op の値だけ減少させます。 sem_op についての正の値は、一般に、 セマフォに結び付けられた資源をリリースするプロセスに対応します。

•   sem_op が負であり、プロセスが別のパーミッション持っている場合の動作は、 セマフォの現在の値に依存します:

    •   セマフォの現在の値が sem_op の絶対値と等しいかそれより大きい場合、セマフォの値を sem_op の絶対値だけ減少させます。 SEM_UNDO が指定されている場合、セマフォの終了時調整値を sem_op の絶対値だけ増加させます。

    •   セマフォの現在値が sem_op の絶対値より小さい場合、次のどれかが発生します:

        •   IPC_NOWAIT を指定した場合、 semop() は戻り値 EAGAIN でただちに復帰します。

        •   それ以外の場合、呼び出し元プロセスは、以下の条件の 1 つが満足されるまで 休眠状態になります:

            •   semctl(2) の IPC_RMID オプションを用いて、他のプロセスがセマフォを削除した場合。 この時 semop() は、戻り値 EIDRM でただちに復帰します。

            •   プロセスが、捕らえるべきシグナルを受け取った場合。 この時そのプロセスは、 sigaction(2) で定義されたように実行を再開します。

            •   セマフォの値が sem_op の絶対値以上になった場合。 この条件が真となった時、セマフォの値を sem_op の絶対値だけ減少させ、セマフォの終了時調整値を sem_op の絶対値だけ増加させます。

    sem_op が負の値であるときは、一般に、 資源が利用可能になるのをプロセスが待っているということです。

•   sem_op が 0 でプロセスが読取り許可を持つ場合、次のどれかが発生します:

    •   現在のセマフォの値が 0 の場合、 semop() はただちに復帰します。

    •   IPC_NOWAIT が指定された場合、 semop() は戻り値 EAGAIN でただちに復帰します。

    •   それ以外の場合、呼び出し元プロセスは、以下の条件の 1 つが満足されるまで 休眠状態になります:

        •   semctl(2) の IPC_RMID オプションを用いて、他のプロセスがセマフォを削除した場合。 この時 semop() は、戻り値 EIDRM でただちに復帰します。

        •   プロセスが、捕らえるべきシグナルを受け取った場合。 この時そのプロセスは、 sigaction(2) で定義されたように実行を再開します。

        •   セマフォの値が 0 となった場合。

プロセスが使用しているセマフォごとに、カーネルは、先に述べたように “終了時調整” 値を保持します。 自発的であれ非自発的にであれ、プロセスが終了するときには、 各セマフォに対する終了時調整値がセマフォの値に追加されます。 これを、プロセスが予期せず終了してしまう場合に 資源を必ず解放することを保証するのに使用可能です。

戻り値

エラー
semop() システムコールは次の場合に失敗します:

[EINVAL]
    semid に対応するセマフォ集合がないか、システムで定義されるプロセス毎の SEM_UNDO 構造体の数の制限が超過しました。

[EACCES]
    操作とセマフォ集合のモードの間で不一致があるため、 パーミッションが拒否されました。

[EAGAIN]
    セマフォはそのプロセスを休眠状態に移行させる値ですが、 IPC_NOWAIT が指定されました。

[E2BIG]
    あまりに多くの操作が指定されました。 [SEMOPM]

[EFBIG]
    sem_num が集合に対する有効なセマフォの範囲内にありませんでした。

[EIDRM]
    セマフォの組は、システムから削除されました。

[EINTR]
    semop() システムコールは、シグナルによって中断されました。

[ENOSPC]
    システムの SEM_UNDO プール [SEMMNU] が、いっぱいになりました。

[ERANGE]
    要求された操作によって、現在のセマフォの値 [SEMVMX] 、もしくはその終了時調整値 [SEMAEM] が、システムによって課されている限界を越えようとしています。

関連項目
semctl(2), semget(2), sigaction(2)

バグ
semop() システムコールは、 IPC_NOWAIT が指定されていてもメモリ待ちでブロックすることがあります。