Manpages

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 [AT] 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); }
/* x と y の 操 作 */
pthread_mutex_unlock(&mut);

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

pthread_mutex_lock(&mut);
/* x と y を 変 更 す る */
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 {
/* x と y の 操 作 */ }
pthread_mutex_unlock(&mut);