semopのヘルプ・マニュアル
日本語 英語
semop --help
man semop
SEMOP(2) Linux Programmer’s Manual SEMOP(2)
名前
semop, semtimedop - セマフォの操作
書式
#include
#include
#include
int semop(int semid, struct sembuf *sops, unsigned nsops);
int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
struct timespec *timeout);
glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):
semtimedop(): _GNU_SOURCE
説明
セマフォ集合 (semaphore set) のメンバーの各セマフォは以下の関連情報を持
っている:
unsigned short semval; /* セマフォ値 */
unsigned short semzcnt; /* ゼロを待つプロセス数 */
unsigned short semncnt; /* 増加を待つプロセス数 */
pid_t sempid; /* 最後に操作を行なったプロセス */
semop() は semid で指定されたセマフォ集合の選択されたセマフォに対して操
作を行う。 sops は nsops 個の要素の配列を指し、配列の各要素は個々のセマ
フォに対する操作を示す。その型は struct sembuf で、次のメンバを持つ:
unsigned short sem_num; /* セマフォ番号 */
short sem_op; /* セマフォ操作 */
short sem_flg; /* 操作フラグ */
sem_flg には IPC_NOWAIT と SEM_UNDO が設定できる。 SEM_UNDO が指定さ れ
た操作は、そのプロセスが終了した時に自動的に取り消される。
sops に含まれる操作の集合は、 配列の順序で、 アトミックに実行される。す
なわち、全ての操作が完全に実行されるか、全く実行されないかのどちらか と
なる。
全 ての操作が直ちに実行できない場合のこのシステムコールの振る舞いは個々
の操作の sem_flg フィールドに IPC_NOWAIT が存在するかによって決まり、後
述のようになる。
そ れぞれの操作はセマフォ集合の sem_num番目のセマフォに対して実行される
。セマフォ集合の最初のセマフォには番号 0 が振られる。そして操作は三種類
あり、 sem_op の値で区別される。
sem_op が正の整数の場合、操作としてその値をセマフォの値 (semval) に加え
る。さらにこの操作に SEM_UNDO が指定されている場合は、システムはこの セ
マフォの プロセス・アンドゥ数 (semadj) を更新する。この操作は必ず実行で
き、プロセスの停止は起こらない。呼び出し元プロセスは対象のセマフォ集 合
を変更する許可がなければならない。
sem_op が 0 の場合、「ゼロまで待つ」操作である。この場合、プロセスはそ
のセマフォ集合に対する読み込み許可がなければならない。 semval が 0 なら
ば 、 操 作 は 直 ち に 行 われる。 semval が 0 でない場合、 sem_flg に
IPC_NOWAIT が指定されていれば、 semop() は失敗し、 errno に EAGAIN が設
定 さ れ る (このとき sops に対する操作は全く実行されない)。 sem_flg に
IPC_NOWAIT が指定されていない場合、 semzcnt (セマフォ値が 0 になるの を
待っているプロセスの数) を 1 増加させて、以下のいずれかが起こるまでプロ
セスを停止 (sleep) する。
· semval が 0 になった: このとき semval の値は 1 減算される。
· セマフォ集合が削除された: このとき semop() は失敗し、 errno に EIDRM
が設定される。
· 呼び出し元プロセスがシグナルを捕獲した: このとき semzcnt の値は 1 減
算され、 semop() は失敗し errno に EINTR が設定される。
· semtimedop() の timeout で指定された制限時間が経過した: こ の と き
semtimedop() は失敗し、 errno に EAGAIN が設定される。
sem_op が 0 未満の場合、プロセスにはそのセマフォ集合を変更する許可がな
ければならない。 semval が sem_op の絶対値以上の場合は、操作は直ちに 実
行 さ れる: semval から sem_op の絶対値が減算される。さらに、この操作に
SEM_UNDO が指定されている場合は、このセマフォのプロセス・ア ン ド ゥ 数
(semadj) を更新する。 semval が sem_op の絶対値より小さく、 sem_flg に
IPC_NOWAIT が指定された場合は、 semop() は失敗し、 errno に EAGAIN が設
定される (このとき sops の操作は全く実行されない)。 IPC_WAIT が指定され
ていなければ、 semncnt (このセマフォの値が増加するのを待っているプロ セ
ス数のカウンタ) を 1 増加させて、以下のいずれかが起こるまでプロセスを停
止 (sleep) する。
· semval が sem_op の絶対値以上になった: このとき semncnt が 1 減算 さ
れ、 semval から sem_op の絶対値が引かれる。この操作に SEM_UNDO が指
定されていた場合にはこのセマフォのプロセス・アンドゥ数 (semadj) も更
新する。
· セ マ フ ォ 集合がシステムから削除された: このとき semop() は失敗し
errno に EIDRM が設定される。
· 呼び出したプロセスがシグナルを捕獲した: このとき semncnt が 1 減算さ
れ、 semop() は失敗し errno に EINTR が設定される。
· semtimedop() の timeout で指定された制限時間が経過した: このとき
semtimedop() は失敗し、 errno に EAGAIN が設定される。
操作が成功した場合、 sops が指す配列によって操作対象となった各セマフ ォ
の sempid メンバーには呼び出したプロセスのプロセス ID が設定される。さ
らに sem_otime に現在時刻が設定される。
semtimedop() 関数の振る舞いは semop() と全く同じだが、呼び出し元プロ セ
スが停止する場合、停止期間の上限が timeout 引き数の指す timespec 構造体
で指定された時間となる点だけが異なる。指定した制限時間に達した場合は 、
semtimedop() は失敗し、 errno に EAGAIN が設定される (このとき sops の
操作は実行されない)。 timeout 引き数が NULL の場合、 semtimedop() 関 数
の振る舞いは semop() 関数と全く同じになる。
返り値
成 功 した場合、 semop() と semtimedop() は 0 を返す。そうでなければ -1
を返し、エラーを示す errno を設定する。
エラー
失敗した場合、 errno に以下のどれかが設定される:
E2BIG nsops 引き数が SEMOPM より大きい。 SEMOPM は一回のシステムコール
で許される操作の最大個数である。
EACCES 呼び出し元プロセスには指定されたセマフォ操作を行うのに必要なアク
セス許可がなく、 CAP_IPC_OWNER ケーパビリティもない。
EAGAIN 操作を直ちに処理することができず、かつ sem_flg に IPC_NOWAIT が
指定されているか timeout で指定された制限時間が経過した。
EFAULT 引き数 sops か timeout が指しているアドレスにアクセスできない。
EFBIG ある操作で、 sem_num の値が 0 未満か、集合内のセマフォの数以上で
ある。
EIDRM セマフォ集合が削除された。
EINTR このシステムコールで停止している時にプロセスがシグナルを捕獲した
。 single(7) 参照。
EINVAL セマフォ集合が存在しないか、 semid が 0 未満であるか、 nsops が
正の数でない。
ENOMEM ある操作で sem_flg に SEM_UNDO が指定されたが、システムにアン ド
ゥ構造体に割り当てる十分なメモリがない。
ERANGE ある操作で sem_op+semval が SEMVMX より大きい。 SEMVMX は semval
の最大値で、その値は実装依存である。
バージョン
semtimedop() は Linux 2.5.52 で初めて登場し、それからカーネル 2.4.22 に
も 移植された。 semtimedop() の glibc でのサポートはバージョン 2.3.3 で
初めて登場した。
準拠
SVr4, POSIX.1-2001.
注意
あるプロセスの sem_undo 構造体は fork(2) で生成された子プロセスには継承
されないが、 execve(2) システムコールの場合は継承される。
semop() はシグナルハンドラによって中断された後に、決して自動的に再開す
ることはない。たとえシグナルハンドラの設定時に SA_RESTART フラグがセ ッ
トされていても再開することはない
semadj はプロセスごとの整数で、 SEM_UNDO フラグを設定して実行された全て
のセマフォ操作の(負数の)カウンタである。 semctl(2) に SETVAL ま た は
SETALL を指定し、セマフォの値が直接設定された場合には、全てのプロセスに
おいて対応する semadj の値がクリアされる。
あるセマフォの semval, sempid, semzcnt, semnct の値はいずれも、適切な操
作を指定して semctl(2) を呼び出すことで取得できる。
セマフォ集合のリソースに関する制限のうち、 semop() に影響を及ぼすものを
以下に挙げる:
SEMOPM 一回の semop() で許される操作の最大数 (32)。 (Linux では、この制
限 値は /proc/sys/kernel/sem の第3フィールドに対応し、読み出しも
変更もできる)。
SEMVMX semval が取り得る最大値: 実装依存 (32767)。
以下の値に関しては実装依存の制限はない。終了時の調整 (adjust on exit)
の 最大値 (SEMAEM)、システム全体のアンドゥ構造体の最大数 (SEMMNU)、プロ
セスあたりのアンドゥ構造体の最大数。
バグ
プロセスが終了する際、プロセスに対応する semadj の 集 合 を 使 っ て 、
SEM_UNDO フラグ付きで実行された全てのセマフォ操作の影響を取り消す。これ
によりある問題が発生する: これらのセマフォの調整を行っていると、中に は
セマフォの値が 0 未満の値にしようとする場合が出てくる。このような場合、
どのように実装するべきか? ひとつの考えられる手法は、全てのセマフォ調整
が 実行されるまで停止することである。しかし、この方法ではプロセスの終了
が長時間にわたって停止されることがあるので望ましくない。しかもどれく ら
い 長時間になるかは分からない。別の選択肢として、このようなセマフォ調整
を完全に無視してしまう方法がある (これはセマフォ操作とし て IPC_NOWAIT
が 指定するのと少し似ている)。 Linux は第三の手法を採用している: セマフ
ォの値を出来るだけ (つまり 0 まで) 減少させて、プロセスの終了を直ちに続
行できるようにしている。
カ ーネル 2.6.x (x <= 10) には、ある状況においてセマフォ値が 0 になるの
を待っているプロセスが、セマフォ値が実際に 0 になったときに起 床 (wake
up) されない、というバグがある。このバグはカーネル 2.6.11 で修正されて
いる。
例
以下の部分的なコードは、セマフォ 0 の値が 0 になるのを待ってから、セ マ
フ ォ の値を 1 加算する処理を、 semop() を使ってアトミック (atomically)
に行う。
struct sembuf sops[2];
int semid;
/* Code to set semid omitted */
sops[0].sem_num = 0; /* Operate on semaphore 0 */
sops[0].sem_op = 0; /* Wait for value to equal 0 */
sops[0].sem_flg = 0;
sops[1].sem_num = 0; /* Operate on semaphore 0 */
sops[1].sem_op = 1; /* Increment value by one */
sops[1].sem_flg = 0;
if (semop(semid, sops, 2) == -1) {
perror("semop");
exit(EXIT_FAILURE);
}
関連項目
semctl(2), semget(2), sigaction(2), capabilities(7), sem_overview(7),
svipc(7), time(7)
Linux 2008-10-04 SEMOP(2)
SEMOP(2) Linux Programmer’s Manual SEMOP(2)
NAME
semop, semtimedop - semaphore operations
SYNOPSIS
#include
#include
#include
int semop(int semid, struct sembuf *sops, unsigned nsops);
int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
struct timespec *timeout);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
semtimedop(): _GNU_SOURCE
DESCRIPTION
Each semaphore in a semaphore set has the following associated values:
unsigned short semval; /* semaphore value */
unsigned short semzcnt; /* # waiting for zero */
unsigned short semncnt; /* # waiting for increase */
pid_t sempid; /* process that did last op */
semop() performs operations on selected semaphores in the set indicated
by semid. Each of the nsops elements in the array pointed to by sops
specifies an operation to be performed on a single semaphore. The ele-
ments of this structure are of type struct sembuf, containing the fol-
lowing members:
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
Flags recognized in sem_flg are IPC_NOWAIT and SEM_UNDO. If an opera-
tion specifies SEM_UNDO, it will be automatically undone when the pro-
cess terminates.
The set of operations contained in sops is performed in array order,
and atomically, that is, the operations are performed either as a com-
plete unit, or not at all. The behavior of the system call if not all
operations can be performed immediately depends on the presence of the
IPC_NOWAIT flag in the individual sem_flg fields, as noted below.
Each operation is performed on the sem_num-th semaphore of the
semaphore set, where the first semaphore of the set is numbered 0.
There are three types of operation, distinguished by the value of
sem_op.
If sem_op is a positive integer, the operation adds this value to the
semaphore value (semval). Furthermore, if SEM_UNDO is specified for
this operation, the system updates the process undo count (semadj) for
this semaphore. This operation can always proceed — it never forces a
process to wait. The calling process must have alter permission on the
semaphore set.
If sem_op is zero, the process must have read permission on the
semaphore set. This is a "wait-for-zero" operation: if semval is zero,
the operation can immediately proceed. Otherwise, if IPC_NOWAIT is
specified in sem_flg, semop() fails with errno set to EAGAIN (and none
of the operations in sops is performed). Otherwise semzcnt (the count
of processes waiting until this semaphore’s value becomes zero) is
incremented by one and the process sleeps until one of the following
occurs:
· semval becomes 0, at which time the value of semzcnt is decremented.
· The semaphore set is removed: semop() fails, with errno set to
EIDRM.
· The calling process catches a signal: the value of semzcnt is decre-
mented and semop() fails, with errno set to EINTR.
· The time limit specified by timeout in a semtimedop() call expires:
semop() fails, with errno set to EAGAIN.
If sem_op is less than zero, the process must have alter permission on
the semaphore set. If semval is greater than or equal to the absolute
value of sem_op, the operation can proceed immediately: the absolute
value of sem_op is subtracted from semval, and, if SEM_UNDO is speci-
fied for this operation, the system updates the process undo count
(semadj) for this semaphore. If the absolute value of sem_op is
greater than semval, and IPC_NOWAIT is specified in sem_flg, semop()
fails, with errno set to EAGAIN (and none of the operations in sops is
performed). Otherwise semncnt (the counter of processes waiting for
this semaphore’s value to increase) is incremented by one and the pro-
cess sleeps until one of the following occurs:
· semval becomes greater than or equal to the absolute value of
sem_op, at which time the value of semncnt is decremented, the abso-
lute value of sem_op is subtracted from semval and, if SEM_UNDO is
specified for this operation, the system updates the process undo
count (semadj) for this semaphore.
· The semaphore set is removed from the system: semop() fails, with
errno set to EIDRM.
· The calling process catches a signal: the value of semncnt is decre-
mented and semop() fails, with errno set to EINTR.
· The time limit specified by timeout in a semtimedop() call expires:
the system call fails, with errno set to EAGAIN.
On successful completion, the sempid value for each semaphore specified
in the array pointed to by sops is set to the process ID of the calling
process. In addition, the sem_otime is set to the current time.
semtimedop() behaves identically to semop() except that in those cases
were the calling process would sleep, the duration of that sleep is
limited by the amount of elapsed time specified by the timespec struc-
ture whose address is passed in the timeout argument. If the specified
time limit has been reached, semtimedop() fails with errno set to
EAGAIN (and none of the operations in sops is performed). If the time-
out argument is NULL, then semtimedop() behaves exactly like semop().
RETURN VALUE
If successful semop() and semtimedop() return 0; otherwise they return
-1 with errno indicating the error.
ERRORS
On failure, errno is set to one of the following:
E2BIG The argument nsops is greater than SEMOPM, the maximum number of
operations allowed per system call.
EACCES The calling process does not have the permissions required to
perform the specified semaphore operations, and does not have
the CAP_IPC_OWNER capability.
EAGAIN An operation could not proceed immediately and either IPC_NOWAIT
was specified in sem_flg or the time limit specified in timeout
expired.
EFAULT An address specified in either the sops or the timeout argument
isn’t accessible.
EFBIG For some operation the value of sem_num is less than 0 or
greater than or equal to the number of semaphores in the set.
EIDRM The semaphore set was removed.
EINTR While blocked in this system call, the process caught a signal;
see signal(7).
EINVAL The semaphore set doesn’t exist, or semid is less than zero, or
nsops has a non-positive value.
ENOMEM The sem_flg of some operation specified SEM_UNDO and the system
does not have enough memory to allocate the undo structure.
ERANGE For some operation sem_op+semval is greater than SEMVMX, the
implementation dependent maximum value for semval.
VERSIONS
semtimedop() first appeared in Linux 2.5.52, and was subsequently back-
ported into kernel 2.4.22. Glibc support for semtimedop() first
appeared in version 2.3.3.
CONFORMING TO
SVr4, POSIX.1-2001.
NOTES
The sem_undo structures of a process aren’t inherited by the child pro-
duced by fork(2), but they are inherited across an execve(2) system
call.
semop() is never automatically restarted after being interrupted by a
signal handler, regardless of the setting of the SA_RESTART flag when
establishing a signal handler.
semadj is a per-process integer which is simply the (negative) count of
all semaphore operations performed specifying the SEM_UNDO flag. When
a semaphore’s value is directly set using the SETVAL or SETALL request
to semctl(2), the corresponding semadj values in all processes are
cleared.
The semval, sempid, semzcnt, and semnct values for a semaphore can all
be retrieved using appropriate semctl(2) calls.
The following limits on semaphore set resources affect the semop()
call:
SEMOPM Maximum number of operations allowed for one semop() call (32)
(on Linux, this limit can be read and modified via the third
field of /proc/sys/kernel/sem).
SEMVMX Maximum allowable value for semval: implementation dependent
(32767).
The implementation has no intrinsic limits for the adjust on exit maxi-
mum value (SEMAEM), the system wide maximum number of undo structures
(SEMMNU) and the per-process maximum number of undo entries system
parameters.
BUGS
When a process terminates, its set of associated semadj structures is
used to undo the effect of all of the semaphore operations it performed
with the SEM_UNDO flag. This raises a difficulty: if one (or more) of
these semaphore adjustments would result in an attempt to decrease a
semaphore’s value below zero, what should an implementation do? One
possible approach would be to block until all the semaphore adjustments
could be performed. This is however undesirable since it could force
process termination to block for arbitrarily long periods. Another
possibility is that such semaphore adjustments could be ignored alto-
gether (somewhat analogously to failing when IPC_NOWAIT is specified
for a semaphore operation). Linux adopts a third approach: decreasing
the semaphore value as far as possible (i.e., to zero) and allowing
process termination to proceed immediately.
In kernels 2.6.x, x <= 10, there is a bug that in some circumstances
prevents a process that is waiting for a semaphore value to become zero
from being woken up when the value does actually become zero. This bug
is fixed in kernel 2.6.11.
EXAMPLE
The following code segment uses semop() to atomically wait for the
value of semaphore 0 to become zero, and then increment the semaphore
value by one.
struct sembuf sops[2];
int semid;
/* Code to set semid omitted */
sops[0].sem_num = 0; /* Operate on semaphore 0 */
sops[0].sem_op = 0; /* Wait for value to equal 0 */
sops[0].sem_flg = 0;
sops[1].sem_num = 0; /* Operate on semaphore 0 */
sops[1].sem_op = 1; /* Increment value by one */
sops[1].sem_flg = 0;
if (semop(semid, sops, 2) == -1) {
perror("semop");
exit(EXIT_FAILURE);
}
SEE ALSO
semctl(2), semget(2), sigaction(2), capabilities(7), sem_overview(7),
svipc(7), time(7)
COLOPHON
This page is part of release 3.22 of the Linux man-pages project. A
description of the project, and information about reporting bugs, can
be found at http://www.kernel.org/doc/man-pages/.
Linux 2008-10-04 SEMOP(2)