マルチスレッドのプログラミング

pthread に相当するものがある同期関数 − 条件変数

条件変数の初期化

cond_init(3T)

#include <thread.h>

int cond_init(cond_t *cv, int type, int arg);

cond_init() は、cv が指す条件変数を初期化します。type には、次のいずれかを指定できます (arg は現在は無視されます)。

0 に初期化されたメモリーに領域を確保することによって、条件変数を初期化することもできます。その場合は、typeUSYNC_THREAD を指定したものと仮定されます。

複数のスレッドから、同じ条件変数を同時に初期化してはいけません。一度初期化した条件変数は他のスレッドが使用している可能性があるので、再初期化してはいけません。

プロセス内スコープでの条件変数

#include <thread.h>

cond_t cv;
int ret;

/* このプロセスの中だけで使用する */
ret = cond_init(cv, USYNC_THREAD, 0); 

プロセス間スコープでの条件変数

#include <thread.h>

cond_t cv;
int ret;

/* すべてのプロセスの間で使用する */
ret = cond_init(&cv, USYNC_PROCESS, 0); 

条件変数の削除

cond_destroy(3T)

#include <thread.h>

int cond_destroy(cond_t *cv);

cond_destroy() は、cv が指す条件変数を削除します。条件変数を格納する領域は解放されません。

条件変数によるブロック

cond_wait(3T)

#include <thread.h>

int cond_wait(cond_t *cv, mutex_t *mp);

cond_wait() は、mp が指す mutex を原子的操作により解放し、cv が指す条件変数で、呼び出しスレッドをブロックします。ブロックされたスレッドを呼び起こすには、cond_signal()cond_broadcast() を使います。また、スレッドはシグナルや fork() の割り込みによっても呼び起こされます。

指定時刻のブロック

cond_timedwait(3T)

#include <thread.h>

int cond_timedwait(cond_t *cv, mutex_t *mp, timestruct_t abstime)

cond_timedwait() は、abstime で指定した時刻を過ぎるとブロック状態を解除する点を除いて、cond_wait() と同じ動作をします。

cond_timedwait() が戻るときは、たとえエラーを戻したときでも、常に mutex は呼び出しスレッドがロックし保持している状態にあります。

cond_timedwait() のブロック状態が解除されるのは、条件変数にシグナルが送られてきたときか、一番最後の引数で指定した時刻を過ぎたときです。時間切れの指定は時刻で行うため、時間切れの時刻を再計算する必要がないので、効率的に条件を再評価できます。

特定のスレッドのブロック解除

cond_signal(3T)

#include <thread.h>

int cond_signal(cond_t *cv);

cond_signal() は、cv が指す条件変数でブロックされている 1 つのスレッドのブロックを解除します。この関数は、シグナルを送ろうとしている条件変数で使用されたのと同じ相互排他ロックを獲得した状態で呼び出してください。そうしないと、関連する条件が評価されてから cond_wait() でブロック状態に入るまでの間に、条件変数にシグナルが送られる可能性があります。この場合、cond_wait() は永久に待ち続けることになります。

全スレッドのブロック解除

cond_broadcast(3T)

#include <thread.h>

int cond_broadcast(cond_t *cv);

cond_broadcast() は、cv が指す条件変数でブロックされている全スレッドのブロックを解除します。スレッドがブロックされていない条件変数に対して cond_broadcast() を実行しても無視されます。