Provided by:
manpages-ja-dev_0.5.0.0.20060115-1_all 
NAME
pthread_cond_init, pthread_cond_destroy, pthread_cond_signal,
pthread_cond_broadcast, pthread_cond_wait, pthread_cond_timedwait -
条件変数の操作
式
#include <pthread.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t
*cond_attr);
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t
*mutex, const struct timespec *abstime);
int pthread_cond_destroy(pthread_cond_t *cond);
明
条件(「条件変数」の省略) は、共優如璽燭紡个垢襪△觸匕譴満たされる
まで、スレッドが実行を停止しプロセッサを手放すことを可能にする同期
装置である。条件に対する基本的な操作は、(述語が真になった場合に)
条件を送信することと、他のスレッドが条件を送信するまでスレッドの実行
を停止して条件を待つことである。
条件変数はいつでも mutex と結びつけられていなければならない。これは、
あるスレッドが条件変数を待とうとしている時に、他のスレッドが、
先のスレッドが実際に条件変数に対して待機するその直前に条件を送信する、
という競合条件を避けるためである。
pthread_cond_init は、条件変数 cond を cond_attr で指定された条件属-
、または cond_attr が NULL であれば、デフォルトの属世能藉化する。
LinuxThreads の実装は、いかなる条件変数の属世砲眤弍していない。
かくして、 cond_attr パラメタは、実のところ無視される。
型 pthread_cond_t の変数は、定数 PTHREAD_COND_INITIALIZER
を使って静的に初期化することもでい襦
pthread_cond_signal は、条件変数 cond
に備えて待機しているスレッドの一つの実行を再開させる。 cond
を待っているスレッドがなければ、何も起こらない。 複数のスレッドが cond
を待っていれば、ただ一つのものだけが再開されるが、どれであるかは
わからない。
pthread_cond_broadcast は cond
に備えて待機している全てのスレッドの実行を再開させる。 cond
を待っているスレッドがなければ、何も起こらない。
pthread_cond_wait は ( pthread_mutex_unlock による) mutex
のアンロックと条件変数 cond
の送信に対する待機を一息で行う。条件変数が送信されるまで
スレッドの実行は停止され、CPU 時間を消費することはない。 mutex は、
pthread_cond_wait
の開始時点で、これを呼び出すスレッドによってロックされていなければ
ならない。 呼び出し側のスレッドに戻る前に pthread_cond_wait は mutex を
( pthread_mutex_lock によって)再び獲得する。
mutex のアンロックと条件変数に対する待機は一息に行われる。従って、
全てのスレッドが条件を送信する前に常に mutex を獲得するのならば、
スレッドが mutex をアンロックする時点と、それが条件変数を待つ時点
との中間の時点で、条件の送信が行なわれる(従って無視される)ことが
不可能となることが保証される。
pthread_cond_timedwait は pthread_cond_wait と同じく、一息で mutex
のアンロックと cond
への待機を行う。しかしまた、待ち時間の長さの設定も行う。 cond が
abstime で指定された時間内に送信されなかったのならば、 mutex mutex
が再獲得され pthread_cond_timedwait は、エラー ETIMEDOUT を返す。
abstime パラメタは time(2) と gettimeofday(2)
の起点を同じくする絶対時間を指定する。すなわち 0 の abstime は 00:00:00
GMT, January 1, 1970 に相当する。
pthread_cond_destroy は条件変数を破壊し、それが保持している可能-
のある資源を開放する。 pthread_cond_destroy
の開始時点で、いかなるスレッドもその条件変数を待っていてはいけない。
LinuxThreads の実装では、いかなる資源も条件変数に付随していない。
従って、 pthread_cond_destroy
は、条件が待機スレッドを持っていないことを確かめる以外に 何もしない。
し
pthread_cond_wait および pthread_cond_timedwait
は、取り消しポイントである。このいずれかの関数で停止している
スレッドが取り消されると、スレッドは直ちに実行を再開し、
pthread_cond_wait と pthread_cond_timedwait の mutex
引数を再ロックし、最後に取り消しを実行する。
結果として、クリーンアップハンドラが呼び出される際に mutex
がロックされていることを保証される。
汗
条件関数は非同期シグナルに対して安全ではない。よって、
シグナルハンドラから呼び出すべい任呂覆ぁF辰法 pthread_cond_signal
または pthread_cond_broadcast
のシグナルハンドラからの呼び出しは、呼び出しスレッドを
デッドロックする可能世ある。
値
全ての条件変数関数は、成功すると 0 を返し、エラーならば非ゼロの
エラーコードを返す。
ー
pthread_cond_init, pthread_cond_signal, pthread_cond_broadcast, および
pthread_cond_wait は、決してエラーコードを返さない。
pthread_cond_timedwait は、エラーに際して次のエラーコードを返す:
ETIMEDOUT
条件変数が abstime
で指定された時限までに送信されなかった。
EINTR pthread_cond_timedwait がシグナルによって割り込まれた。
pthread_cond_destroy 関数は、エラーに際して次のエラーコードを返す:
EBUSY いずれかのスレッドが現在 cond に対して待機している。
者
Xavier Leroy <Xavier.Leroy@inria.fr>
目
pthread_condattr_init(3), pthread_mutex_lock(3),
pthread_mutex_unlock(3), gettimeofday(2), nanosleep(2).
例
二つの共擁竸 x と y があって、mutex mut
により保護されているとしよう。更に、条件変数 cond があって、 x が y
より大いなれば、送信されるとしよう。
int x,y;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
x が y より大いなるまで待つには、 次のようにすれば良い:
pthread_mutex_lock(&mut);
while (x <= y) {
pthread_cond_wait(&cond, &mut);
}
/* x y */
pthread_mutex_unlock(&mut);
x を y よりも大いするような x と y
の操作は必要に応じて、条件を送信せねばならない:
pthread_mutex_lock(&mut);
/* x y */
if (x > y) pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mut);
起動すべぅ好譽奪匹最大限一つであることが確実ならば (例えば、 x と y
を通じて交流するスレッドが二つしかないのならば)、 pthread_cond_signal
を pthread_cond_broadcast の、少しばかり効率的な代替物として使用でい襦
疑問のある場合には pthread_cond_broadcast を使用せよ。
x が y より大いなるのを五秒の時限を設けて待つには次のようにする:
struct timeval now;
struct timespec timeout;
int retcode;
pthread_mutex_lock(&mut);
gettimeofday(&now);
timeout.tv_sec = now.tv_sec + 5;
timeout.tv_nsec = now.tv_usec * 1000;
retcode = 0;
while (x <= y && retcode != ETIMEDOUT) {
retcode = pthread_cond_timedwait(&cond, &mut, &timeout);
}
if (retcode == ETIMEDOUT) {
/* */
} else {
/* x y */
}
pthread_mutex_unlock(&mut);
LinuxThreads PTHREAD_COND(3)