PTHREAD_COND

Section: C Library Functions (3)
Updated: LinuxThreads
IndexJM Home Page

 

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は、条件変数condcond_attrで指定された条件属性、またはcond_attrNULLであれば、デフォルトの属性で初期化する。 LinuxThreads の実装は、いかなる条件変数の属性にも対応していない。 かくして、cond_attrパラメタは、実のところ無視される。

pthread_cond_tの変数は、定数PTHREAD_COND_INITIALIZERを使って静的に初期化することもできる。

pthread_cond_signalは、条件変数condに備えて待機しているスレッドの一つの実行を再開させる。condを待っているスレッドがなければ、何も起こらない。 複数のスレッドがcondを待っていれば、ただ一つのものだけが再開されるが、どれであるかは わからない。

pthread_cond_broadcastcondに備えて待機している全てのスレッドの実行を再開させる。condを待っているスレッドがなければ、何も起こらない。

pthread_cond_waitは (pthread_mutex_unlockによる)mutexのアンロックと条件変数condの送信に対する待機を一息で行う。条件変数が送信されるまで スレッドの実行は停止され、CPU 時間を消費することはない。mutexは、pthread_cond_waitの開始時点で、これを呼び出すスレッドによってロックされていなければ ならない。 呼び出し側のスレッドに戻る前にpthread_cond_waitmutexを (pthread_mutex_lockによって)再び獲得する。

mutex のアンロックと条件変数に対する待機は一息に行われる。従って、 全てのスレッドが条件を送信する前に常に mutex を獲得するのならば、 スレッドが mutex をアンロックする時点と、それが条件変数を待つ時点 との中間の時点で、条件の送信が行なわれる(従って無視される)ことが 不可能となることが保証される。

pthread_cond_timedwaitpthread_cond_waitと同じく、一息でmutexのアンロックとcondへの待機を行う。しかしまた、待ち時間の長さの設定も行う。condabstimeで指定された時間内に送信されなかったのならば、 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_waitpthread_cond_timedwaitmutex引数を再ロックし、最後に取り消しを実行する。 結果として、クリーンアップハンドラが呼び出される際に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).

 

二つの共有変数xyがあって、mutex mutにより保護されているとしよう。更に、条件変数condがあって、xyより大きくなれば、送信されるとしよう。

int x,y;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

xyより大きくなるまで待つには、 次のようにすれば良い:

pthread_mutex_lock(&mut);
while (x <= y) { pthread_cond_wait(&cond, &mut);
}
pthread_mutex_unlock(&mut);

xyよりも大きくするようなxyの操作は必要に応じて、条件を送信せねばならない:

pthread_mutex_lock(&mut);
if (x > y) pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mut);

起動すべきスレッドが最大限一つであることが確実ならば (例えば、xyを通じて交流するスレッドが二つしかないのならば)、pthread_cond_signalpthread_cond_broadcastの、少しばかり効率的な代替物として使用できる。 疑問のある場合にはpthread_cond_broadcastを使用せよ。

xyより大きくなるのを五秒の時限を設けて待つには次のようにする:

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 {
}
pthread_mutex_unlock(&mut);


関連キーワード

cond,pthread,mutex,PTHREAD,mut,wait,COND,timedwait,broadcast,int 

Index

NAME
書式
説明
取り消し
非同期シグナルに対する安全性
返り値
エラー
著者
関連項目

This document was created byman2html, using the manual pages.
Time: 15:49:14 GMT, July 11, 2021