条件変数は、ある条件が真になるまでスレッドを原子的にブロックしたいときに使用します。必ず相互排他ロックとともに使用します。
条件変数を使うと、特定の条件が真になるまでスレッドを原子的にブロックできます。この条件判定は、相互排他ロックにより保護された状態で行います。
条件が偽のとき、スレッドは通常は条件変数でブロック状態に入り、相互排他ロックを原子的操作により解除して、条件が変更されるのを待ちます。別のスレッドが条件を変更すると、そのスレッドはそれに関連する条件変数にシグナルを送り、その条件変数でブロックしているスレッドを呼び起こします。呼び起こされたスレッドは再度相互排他ロックを獲得し、条件を再び評価します。
異なるプロセスに所属するスレッドの間で、条件変数を使って同期をとるためには、連携するそれらのプロセスの間で共有される書き込み可能なメモリーに、条件変数の領域を確保する必要があります。
スケジューリング方針は、ブロックされたスレッドがどのように呼び起こさるかを決定します。デフォルト SCHED_OTHER の場合、スレッドは優先順位に従って呼び起こされます。
条件変数の属性は、使用する前に設定して初期化しておかなければなりません。条件変数の属性を操作する関数を表 4-4 に示します。
表 4-4 条件変数の属性
操作 |
参照先 |
---|---|
条件変数の属性の初期化 | |
条件変数の属性の削除 | |
条件変数のスコープの設定 | |
条件変数のスコープの取得 |
条件変数のスコープ定義について、Solaris スレッドと POSIX スレッドの相違点を表 4-5 に示します。
表 4-5 条件変数のスコープの比較
Solaris |
POSIX |
定義 |
---|---|---|
USYNC_PROCESS |
PTHREAD_PROCESS_SHARED |
このプロセスと他のプロセスのスレッドの間で同期をとるために使用する。 |
USYNC_THREAD |
PTHREAD_PROCESS_PRIVATE |
このプロセスのスレッドの間でだけ同期をとるために使用する。 |
pthread_condattr_init(3THR) は、このオブジェクトに関連付けられた属性をデフォルト値に初期化します。各属性オブジェクトのための記憶領域は、実行時にスレッドシステムによって割り当てられます。この関数が呼び出されたときの pshared 属性のデフォルト値は PTHREAD_PROCESS_PRIVATE で、初期化された条件変数を 1 つのプロセスの中だけで使用できるという意味です。
プロトタイプ: int pthread_condattr_init(pthread_condattr_t *cattr); #include <pthread.h> pthread_condattr_t cattr; int ret; /* initialize an attribute to default value */ ret = pthread_condattr_init(&cattr); |
cattr は不透明なデータ型で、システムによって割り当てられた属性オブジェクトを格納します。cattr のスコープとして取りうる値は、PTHREAD_PROCESS_PRIVATE (デフォルト) と PTHREAD_PROCESS_SHARED です。
条件変数属性を再使用するには、pthread_condattr_destroy(3T) によって事前に削除しなければなりません。pthread_condattr_init() 呼び出しは、不透明なオブジェクトへのポインタを戻します。そのオブジェクトが削除されないと、結果的にメモリーリークを引き起こします。
正常終了時は 0 です。それ以外の戻り値は、エラーが発生したことを示します。以下のいずれかの条件が検出されると、この関数は失敗し、対応する値を返します。
pthread_condattr_destroy(3THR) は記憶領域を解除し、属性オブジェクトを無効にします。
プロトタイプ: int pthread_condattr_destroy(pthread_condattr_t *cattr); #include <pthread.h> pthread_condattr_t cattr; int ret; /* 属性を削除する */ ret = pthread_condattr_destroy(&cattr); |
正常終了時は 0 です。それ以外の戻り値は、エラーが発生したことを示します。以下の条件が検出されると、この関数は失敗し、対応する値を返します。
pthread_condattr_setpshared(3THR) は、プロセス専用 (プロセス内) とシステム共通 (プロセス間) のどちらかに条件変数のスコープを設定します。pshared 属性を PTHREAD_PROCESS_SHARED 状態に設定して条件変数を生成し、その条件変数が共有メモリー内に存在する場合、その条件変数は複数のプロセスのスレッドの間で共有できます。これは、オリジナルの Solaris スレッドにおいて mutex_init() で USYNC_PROCESS フラグを使用するのに相当します。
mutex の pshared 属性を PTHREAD_PROCESS_PRIVATE (デフォルト値) に設定した場合、その mutex を操作できるのは同じプロセスで生成されたスレッドに限られます。PTHREAD_PROCESS_PRIVATE を使用した場合、その動作はオリジナルの Solaris スレッドにおいて cond_init() 呼び出しで USYNC_THREAD フラグを使用したとき、すなわち局所条件変数と同じになります。PTHREAD_PROCESS_SHARED は広域条件変数に相当します。
プロトタイプ: int pthread_condattr_setpshared(pthread_condattr_t *cattr, int pshared); #include <pthread.h> pthread_condattr_t cattr; int ret; /* 全プロセス */ ret = pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED); /* 1 つのプロセス内 */ ret = pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_PRIVATE); |
正常終了時は 0 です。それ以外の戻り値は、エラーが発生したことを示します。以下の条件が検出されると、この関数は失敗し、対応する値を返します。
pthread_condattr_getpshared(3THR) は属性オブジェクト cattr の pshared の現在のスコープ値を取得します。これは PTHREAD_PROCESS_SHARED と PTHREAD_PROCESS_PRIVATE のどちらかです。
プロトタイプ: int pthread_condattr_getpshared(const pthread_condattr_t *cattr, int *pshared); #include <pthread.h> pthread_condattr_t cattr; int pshared; int ret; /* 条件変数の pshared 値を取得する */ ret = pthread_condattr_getpshared(&cattr, &pshared); |
正常終了時は 0 です。それ以外の戻り値は、エラーが発生したことを示します。以下の条件が検出されると、この関数は失敗し、対応する値を返します。