条件変数は、ある条件が真になるまでスレッドを不可分にブロックしたいときに使用します。必ず相互排他ロックとともに使用します。
条件変数を使うと、特定の条件が真になるまでスレッドを不可分にブロックできます。この条件判定は、相互排他ロックにより保護された状態で行います。
条件が偽のとき、スレッドは通常は条件変数でブロック状態に入り、相互排他ロックを原子的操作により解除して、条件が変更されるのを待ちます。別のスレッドによって条件が変更されると、そのスレッドは関連した条件変数にシグナルを送り、1 つ以上の待機スレッドに次の処理を実行させることができます。
呼び起こす
相互排他ロックを再度獲得する
条件を再評価する
次の条件のプロセスの間でスレッドの同期を取るには、条件変数を使用します。
スレッドが書き込み可能なメモリーに割り当てられている
連携する複数のプロセスがメモリーを共有している
スケジューリングポリシーは、ブロックされたスレッドがどのように呼び起こされるかを決定します。デフォルトスケジューリングポリシー SCHED_OTHER は、スレッドが呼び起こされる順序を指定していません。SCHED_FIFO および SCHED_RR リアルタイムスケジューリングポリシーの下では、スレッドは優先順位に従って呼び起こされます。
条件変数の属性は、使用する前に設定して初期化しておかなければなりません。表 4–4 に、条件変数の属性を操作する関数を示します。
表 4–4 条件変数の属性
操作 |
参照先 |
---|---|
条件変数の属性の初期化 | |
条件変数の属性の削除 | |
条件変数のスコープの設定 | |
条件変数のスコープの取得 | |
クロック選択条件変数の属性の取得 | |
クロック選択条件変数の属性の設定 |
このオブジェクトに割り当てられた属性をデフォルト値に初期化するには、pthread_condattr_init(3C) を使用します。各属性オブジェクトのための記憶領域は、実行時にスレッドシステムによって割り当てられます。
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);
この関数が呼び出されたときの pshared 属性のデフォルト値は PTHREAD_PROCESS_PRIVATE です。 pshared がこの値の場合は、初期化された条件変数がプロセス内で使用可能であることを示します。
cattr は不透明なデータ型で、システムによって割り当てられた属性オブジェクトを格納します。cattr のスコープとして取り得る値は、PTHREAD_PROCESS_PRIVATE と PTHREAD_PROCESS_SHARED です。PTHREAD_PROCESS_PRIVATE はデフォルト値です。
条件変数の属性を再利用するには、まず、この属性を pthread_condattr_destroy(3C) で初期化し直す必要があります。pthread_condattr_init() 呼び出しは、不透明なオブジェクトへのポインタを戻します。そのオブジェクトが削除されないと、結果的にメモリーリークを引き起こします。
pthread_condattr_init() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。以下の条件が検出されると、この関数は失敗し、次の値を戻します。
ENOMEM
説明:メモリーが足りなくて、スレッド属性オブジェクトを初期化できません。
EINVAL
説明:cattr で指定された値が無効です。
記憶領域を削除し、属性オブジェクトを無効にするには、pthread_condattr_destroy(3C) を使用します。
int pthread_condattr_destroy(pthread_condattr_t *cattr);
#include <pthread.h> pthread_condattr_t cattr; int ret; /* destroy an attribute */ ret = pthread_condattr_destroy(&cattr);
pthread_condattr_destroy() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。以下の条件が検出されると、この関数は失敗し、対応する値を返します。
EINVAL
説明:cattr で指定された値が無効です。
pthread_condattr_setpshared(3C) は、条件変数のスコープをプロセス専用 (プロセス内) またはシステム共通 (プロセス間) に設定します。
int pthread_condattr_setpshared(pthread_condattr_t *cattr, int pshared);
#include <pthread.h> pthread_condattr_t cattr; int ret; /* all processes */ ret = pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED); /* within a process */ ret = pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_PRIVATE);
共有メモリー内に pshared 属性を生成し、その条件変数を PTHREAD_PROCESS_SHARED に設定した場合、この条件変数は複数のプロセスのスレッド間で共有できます。
mutex の pshared 属性を PTHREAD_PROCESS_PRIVATE に設定した場合、その mutex を操作できるのは同じプロセスで生成されたスレッドだけです。PTHREAD_PROCESS_PRIVATE はデフォルト値です。PTHREAD_PROCESS_PRIVATE は、局所条件変数として動作します。PTHREAD_PROCESS_SHARED の動作は、大域条件変数に相当します。
pthread_condattr_setpshared () は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。以下の条件が検出されると、この関数は失敗し、対応する値を返します。
EINVAL
説明:cattr または pshared の値が無効です。
pthread_condattr_getpshared(3C) は、属性オブジェクト cattr の pshared の現在のスコープ値を取得します。
int pthread_condattr_getpshared(const pthread_condattr_t *restrict cattr, int *restrict pshared);
#include <pthread.h> pthread_condattr_t cattr; int pshared; int ret; /* get pshared value of condition variable */ ret = pthread_condattr_getpshared(&cattr, &pshared);
属性オブジェクトの値は、PTHREAD_PROCESS_SHARED か PTHREAD_PROCESS_PRIVATE になります。
pthread_condattr_getpshared () は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。以下の条件が検出されると、この関数は失敗し、次の値を返します。
EINVAL
説明:cattr の値が無効です。
attr が参照する初期化された属性オブジェクト内のクロック属性を設定するには、pthread_condattr_setclock(3C) 関数を使用します。pthread_condattr_setclock() が、CPU 時間クロックを表す clock_id 引数を指定して呼び出された場合、その呼び出しは失敗します。クロック属性は、pthread_cond_timedwait() のタイムアウトサービスを測定するために使用されるクロックのクロック ID です。クロック属性のデフォルト値は、システムクロック CLOCK_REALTIME を表します。この時点で、クロック属性に対して取り得るほかの値は CLOCK_MONOTONIC だけです。
int pthread_condattr_setclock(pthread_condattr_t attr, clockid_t clock_id);
#include <pthread.h> pthread_condattr_t attr clockid_t clock_id int ret ret = pthread_condattr_setclock(&attr &clock_id
pthread_condattr_setclock() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。以下の条件が検出されると、この関数は失敗し、次の値を返します。
EINVAL
説明:clock_id で指定された値が既知のクロックを表していないか、または CPU 時間クロックです。
attr が参照する属性オブジェクトからクロック属性の値を取得するには、pthread_condattr_getclock(3C) 関数を使用します。クロック属性は、pthread_cond_timedwait() のタイムアウトサービスを測定するために使用されるクロックのクロック ID です。
int pthread_condattr_getclock(const pthread_condattr_t *restrict attr, clockid_t *restrict clock_id);
#include <pthread.h> pthread_condattr_t attr clockid_t clock_id int ret ret = pthread_condattr_getclock(&attr &clock_id
pthread_condattr_getclock() は、正常終了時に 0 を返し、attr の clock 属性の値を clock_id 引数が参照するオブジェクトに格納します。それ以外の戻り値は、エラーが発生したことを示します。以下の条件が検出されると、この関数は失敗し、次の値を返します。
EINVAL
説明:attr の値が無効です。