Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-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 がロックされていること を保証される。
非同期シグナルに対する安全性
条件関数は非同期シグナルに対して安全ではない。よって、 シグナルハンドラから呼び出すべきで はない。特に、 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)