pthread_mutexattr_setprotocol(3T) は、mutex 属性オブジェクトのプロトコル属性を設定します。
#include <pthread.h> int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol); |
attr は、先の pthread_mutexattr_init() の呼び出しによって作成された mutex 属性オブジェクトを指します。
protocol には、mutex 属性オブジェクトに適用されるプロトコルを指定します。
pthread.h に定義可能な protocol の値は、PTHREAD_PRIO_NONE、PTHREAD_PRIO_INHERIT、または PTHREAD_PRIO_PROTECT です。
PTHREAD_PRIO_NONE
PTHREAD_PRIO_INHERIT
スレッド (thrd1 など) が所有する 1 つまたは複数の mutex が、より優先順位の高いスレッドによってブロックされている場合、これらの mutex が PTHREAD_PRIO_INHERIT で初期化されていると、このプロトコル値はスレッド (thrd1) の優先順位とスケジューリングに影響します。thrd1 は、より高い優先順位または thrd1 が所有する mutex を待っているスレッドの最高優先順位で実行されます。
thrd1 が別のスレッド thrd3 が所有する mutex をブロックしている場合、同様の優先順位継承効果が thrd3 に対して再帰的に伝播されます。
PTHREAD_PRIO_INHERIT を使用して、優先順位が逆転しないようにしてください。優先順位の低いスレッドが、そのスレッドより優先順位の高いスレッドが必要としているロックを保持していると、優先順位が逆転します。優先順位の高いスレッドは、優先順位の低いスレッドがロックを解除するまで実行を続行できないため、各スレッドは本来の優先順位が逆転しているかのように扱われます。
シンボル _POSIX_THREAD_PRIO_INHERIT が定義されている場合、プロトコル属性値 PTHREAD_PRIO_INHERIT で初期化された mutex では、その mutex の所有者が終了すると Solaris オペレーティング環境で次の動作が発生します。
所有者終了時の動作は、pthread_mutexattr_setrobust_np() の robustness 引数の値によって異なります。
mutex のロックが解除されます。
次の所有者がその mutex を獲得し、エラーコード EOWNERDEAD が返されます。
mutex の次の所有者は、mutex によって保護されている状態を整合させるよう試行する必要があります。これは、前の所有者が終了したときに状態が不整合のままになっている可能性があるためです。所有者が状態を整合させることに成功すると、その mutex に対して pthread_mutex_init() を呼び出して、mutex をロック解除します。
pthread_mutex_init() が前の初期化で呼び出されたが、まだ mutex を削除していない場合、mutex は初期化し直されません。
所有者が状態を整合させることができない場合は、pthread_mutex_init() は呼び出さず、mutex をロック解除します。この場合には、すべての待機者が呼び起こされ、それ以降の pthread_mutex_lock() へのすべての呼び出しは mutex の獲得に失敗し、エラーコード ENOTRECOVERABLE が返されます。この時点で、pthread_mutex_destroy() を呼び出して mutex を削除し、pthread_mutex_init() を呼び出して初期化し直すことによって、mutex の状態を整合させることができます。
EOWNERDEAD を持つロックを獲得したスレッドが終了すると、次の所有者がエラーコード EOWNERDEAD を持つロックを獲得します。
PTHREAD_PRIO_PROTECT
あるスレッドが、PTHREAD_PRIO_PROTECT で初期化された 1 つまたは複数の mutex を所有する場合に、このプロトコル値は、スレッド (thrd2 など) の優先順位とスケジューリングに影響します。thrd2 は、より高い優先順位または自分が所有しているすべての mutex の中で最も高い優先順位で実行します。thrd2 が所有するいずれかの mutex でブロックされているより優先度の高いスレッドは、thrd2 のスケジューリングには影響を与えません。
スレッドが PTHREAD_PRIO_INHERIT または PTHREAD_PRIO_PROTECT で初期化された mutex を所有しており、sched_setparam() の呼び出しなどによってそのスレッドの元の優先順位が変更されている場合は、スケジューラは新しい優先順位のスケジューリングキューの末尾にそのスレッドを移動しません。同様に、PTHREAD_PRIO_INHERIT または PTHREAD_PRIO_PROTECT で初期化された mutex をスレッドがロック解除して、そのスレッドの元の優先順位が変更されている場合は、スケジューラは新しい優先順位のスケジューリングキューの末尾にそのスレッドを移動しません。
PTHREAD_PRIO_INHERIT で初期化された mutex と PTHREAD_PRIO_PROTECT で初期化された mutex を複数同時に所有しているスレッドは、これらのプロトコルのいずれかで獲得された最高の優先順位で実行します。
pthread_mutexattr_setprotocol() は、正常終了すると 0 を返します。それ以外の戻り値は、エラーが発生したことを示しています。
次のどちらかの条件が検出されると、pthread_mutexattr_setprotocol() は失敗し、対応する値を返します。
_POSIX_THREAD_PRIO_INHERIT と_POSIX_THREAD_PRIO_PROTECT のどちらのオプションも定義されておらず、この実装はこの関数をサポートしていません。
protocol で指定された値はサポートされていない値です。
次のどちらかの条件が検出されると、pthread_mutexattr_setprotocol() は失敗し、対応する値を返します。