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

相互排他ロック属性

相互排他ロック (mutex) は、スレッドの実行を直列化したいときに使用します。相互排他ロックでスレッド間の同期をとるときは、通常、コードの危険領域が複数のスレッドによって同時に実行されないようにするという方法を使用します。単一のスレッドのコードを保護する目的で相互排他ロックを使用することもできます。

デフォルトの mutex 属性を変更するには、属性オブジェクトを宣言して初期化します。多くの場合、アプリケーションの先頭部分の一箇所で設定しますので、mutex 属性は、すばやく見つけて簡単に変更できます。表 4–1 に、mutex 属性を操作する関数を示します。

表 4–1 mutex 属性ルーチン

操作 

参照先 

mutex 属性オブジェクトの初期化 

pthread_mutexattr_init の構文」

mutex 属性オブジェクトの削除 

pthread_mutexattr_destroy の構文」

mutex のスコープ設定 

pthread_mutexattr_setpshared の構文」

mutex のスコープの値の取得 

pthread_mutexattr_getpshared の構文」

mutex の型属性の設定 

pthread_mutexattr_settype の構文」

mutex の型属性の取得 

pthread_mutexattr_gettype の構文」

mutex 属性のプロトコルの設定 

pthread_mutexattr_setprotocol の構文」

mutex 属性のプロトコルの取得 

pthread_mutexattr_getprotocol の構文」

mutex 属性の優先順位上限の設定 

pthread_mutexattr_setprioceiling の構文」

mutex 属性の優先順位上限の取得 

pthread_mutexattr_getprioceiling の構文」

mutex の優先順位上限の設定 

pthread_mutex_setprioceiling の構文」

mutex の優先順位上限の取得 

pthread_mutex_getprioceiling の構文」

mutex の堅牢度属性の設定 

pthread_mutexattr_setrobust_np の構文」

mutex の堅牢度属性の取得 

pthread_mutexattr_getrobust_np の構文」

mutex 属性オブジェクトの初期化

mutex オブジェクトに関連付けられた属性をデフォルト値に初期化するには、pthread_mutexattr_init(3C) を使用します。各属性オブジェクトのための記憶領域は、実行時にスレッドシステムによって割り当てられます。

pthread_mutexattr_init の構文

int pthread_mutexattr_init(pthread_mutexattr_t *mattr);
#include <pthread.h>

pthread_mutexattr_t mattr;
int ret;

/* initialize an attribute to default value */
ret = pthread_mutexattr_init(&mattr); 

mattr不透明な型で、システムによって割り当てられた属性オブジェクトを格納します。mattr オブジェクト内の属性については、表 4–2 を参照してください。

mutex 属性オブジェクトを再度初期化する場合は、あらかじめ pthread_mutexattr_destroy(3C) を呼び出して、オブジェクトを削除しておく必要があります。pthread_mutexattr_init() を呼び出すと、不透明なオブジェクトが割り当てられます。そのオブジェクトが削除されないと、結果的にメモリーリークを引き起こします。

表 4–2 mattr のデフォルトの属性値

属性 

値 

結果 

pshared

PTHREAD_PROCESS_PRIVATE

初期化された mutex を 1 つのプロセス内で使用できます。その mutex を操作できるのは同じプロセスで生成されたスレッドだけです。 

type

PTHREAD_MUTEX_DEFAULT

Solaris Pthreads 実装では、PTHREAD_MUTEX_DEFAULT は、デッドロックを検出しない PTHREAD_MUTEX_NORMAL に割り当てられます。

プロトコル

PTHREAD_PRIO_NONE

スレッドの優先順位とスケジューリングは、そのスレッドが所有する mutex の優先順位の影響を受けません。 

prioceiling

– 

prioceiling の値は、sched_get_priority_min() および sched_get_priority_max() 関数によって返される、SCHED_FIFO 方針に関する既存の優先順位の範囲から取得されます。この優先順位の範囲は、mutex が作成された Solaris バージョンによって決定されます。

robustness

PTHREAD_MUTEX_STALLED_NP

mutex の所有者が終了すると、この mutex に関する pthread_mutex_lock() への将来のすべての呼び出しは進行過程からブロックされます。

pthread_mutexattr_init の戻り値

pthread_mutexattr_init() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。以下のいずれかの条件が検出されると、この関数は失敗し、次の値を返します。


ENOMEM

説明:

メモリー不足のため、mutex 属性オブジェクトを初期化できません。

mutex 属性オブジェクトの削除

pthread_mutexattr_destroy(3C) は、pthread_mutexattr_init() によって生成された属性オブジェクトの管理に使用されていた記憶領域の割り当てを解除します。

pthread_mutexattr_destroy の構文

int pthread_mutexattr_destroy(pthread_mutexattr_t *mattr)
#include <pthread.h> 
pthread_mutexattr_t mattr; 
int ret; 
/* destroy an attribute */ 
ret = pthread_mutexattr_destroy(&mattr); 

pthread_mutexattr_destroy の戻り値

pthread_mutexattr_destroy() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。以下の条件が検出されると、この関数は失敗し、対応する値を返します。


EINVAL

説明:

mattr で指定された値が無効です。

mutex のスコープ設定

pthread_mutexattr_setpshared(3C) は、mutex 変数のスコープを設定します。

pthread_mutexattr_setpshared の構文

int pthread_mutexattr_setpshared(pthread_mutexattr_t *restrict mattr,
         int *restrict pshared);
#include <pthread.h> 
pthread_mutexattr_t mattr; 
int ret; 
ret = pthread_mutexattr_init(&mattr); 
/* * resetting to its default value: private */ 
ret = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE);

mutex 変数のスコープは、プロセス専用 (プロセス内) またはシステム共通 (プロセス間) です。複数のプロセスのスレッド間で mutex を共有させるには、pshared 属性を PTHREAD_PROCESS_SHARED に設定して、共有メモリー内に mutex を生成します。

mutex の pshared 属性を PTHREAD_PROCESS_PRIVATE に設定した場合、その mutex を操作できるのは同じプロセスで生成されたスレッドだけです。

pthread_mutexattr_setpshared の戻り値

pthread_mutexattr_setpshared () は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。以下の条件が検出されると、この関数は失敗し、対応する値を返します。


EINVAL

説明:

mattr で指定された値が無効です。

mutex のスコープの値の取得

pthread_mutexattr_getpshared(3C) は、pthread_mutexattr_setpshared() によって定義された mutex 変数のスコープを返します。

pthread_mutexattr_getpshared の構文

int pthread_mutexattr_getpshared(pthread_mutexattr_t *restrict mattr, 
          int *restrict pshared);
#include <pthread.h> 
pthread_mutexattr_t mattr; 
int pshared, ret; 
/* get pshared of mutex */ 
ret = pthread_mutexattr_getpshared(&mattr, &pshared); 

属性オブジェクト mattrpshared の現在値を取得します。これは PTHREAD_PROCESS_SHAREDPTHREAD_PROCESS_PRIVATE のどちらかです。

pthread_mutexattr_getpshared の戻り値

pthread_mutexattr_getpshared () は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。以下の条件が検出されると、この関数は失敗し、対応する値を返します。


EINVAL

説明:

mattr で指定された値が無効です。

mutex の型属性の設定

pthread_mutexattr_settype(3C) は、mutex の型 (type) 属性を設定します。

pthread_mutexattr_settype の構文

#include <pthread.h>

int pthread_mutexattr_settype(pthread_mutexattr_t  *attr , int type);

型 (type) 属性のデフォルト値は PTHREAD_MUTEX_DEFAULT です。

型 (type) 引数は mutex の型を指定します。以下に、有効な mutex 型を示します。


PTHREAD_MUTEX_NORMAL

説明:

この型の mutex はデッドロックを検出しません。スレッドが、この mutex をロック解除しないでもう一度ロックしようとすると、mutex はデッドロックします。別のスレッドによってロックされた mutex をロック解除しようとした場合、引き起こされる動作は未定義です。また、ロック解除された mutex をロック解除しようとした場合、引き起こされる動作は不定です。


PTHREAD_MUTEX_ERRORCHECK

説明:

この型の mutex はエラーチェックを行います。スレッドがこの mutex をロック解除しないでもう一度ロックしようとすると、エラーを返します。あるスレッドがロックした mutex を別のスレッドがロック解除しようとすると、エラーが返されます。また、ロック解除された mutex をロック解除しようとするとエラーを返します。


PTHREAD_MUTEX_RECURSIVE

説明:

スレッドがこの mutex をロック解除しないでもう一度ロックしようとすると、正常にロックできます。PTHREAD_MUTEX_NORMAL 型の mutex ではロックを繰り返すとデッドロックが発生しますが、この型の mutex では発生しません。複数回ロックされた mutex を別のスレッドが獲得するときには、その前に同じ回数ロック解除する必要があります。あるスレッドがロックした mutex を別のスレッドがロック解除しようとすると、エラーが返されます。また、ロック解除された mutex をロック解除しようとするとエラーを返します。


PTHREAD_MUTEX_DEFAULT

説明:

この属性は、ほかの mutex 型に割り当てることができます。Solaris の実装では、この属性は PTHREAD_PROCESS_NORMAL に割り当てられます。

pthread_mutexattr_settype の戻り値

pthread_mutexattr_settype 関数は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。


EINVAL

説明:

type または attr の値が無効です。

mutex の型属性の取得

pthread_mutexattr_gettype(3C) は、pthread_mutexattr_settype() によって設定された mutex の型 (type) 属性を取得します。

pthread_mutexattr_gettype の構文

#include <pthread.h>

int pthread_mutexattr_gettype(pthread_mutexattr_t  *restrict attr , 
int  *restrict type);

型 (type) 属性のデフォルト値は PTHREAD_MUTEX_DEFAULT です。

型 (type) 引数は mutex の型を指定します。有効な mutex 型を以下に示します。

それぞれの型については、pthread_mutexattr_settype の構文」を参照してください。

pthread_mutexattr_gettype の戻り値

pthread_mutexattr_gettype() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。


EINVAL

説明:

type で指定された値が無効です。

mutex 属性のプロトコルの設定

pthread_mutexattr_setprotocol(3C) は、mutex 属性オブジェクトのプロトコル属性を設定します。

pthread_mutexattr_setprotocol の構文

#include <pthread.h> 
int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, 
          int protocol);

attr は、先の pthread_mutexattr_init() の呼び出しによって作成された mutex 属性オブジェクトを指します。

protocol には、mutex 属性オブジェクトに適用されるプロトコルを指定します。

pthread.h に定義されている protocol の値は、次の値のうちのいずれか 1 つです。 PTHREAD_PRIO_NONEPTHREAD_PRIO_INHERIT、または PTHREAD_PRIO_PROTECT です。

PTHREAD_PRIO_INHERIT および PTHREAD_PRIO_PROTECT mutex 属性を使用できるのは、リアルタイム (RT) スケジューリングクラス SCHED_FIFO または SCHED_RR で実行されている特権付きプロセスだけです。

スレッドは、 PTHREAD_PRIO_INHERIT で初期化された mutex と PTHREAD_PRIO_PROTECT で初期化された mutex を複数同時に所有できます。この場合、スレッドは、これらのプロトコルのいずれかで獲得された最高の優先順位で実行します。

pthread_mutexattr_setprotocol の戻り値

pthread_mutexattr_setprotocol() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。

次のどちらかの条件が検出されると、pthread_mutexattr_setprotocol() は失敗し、対応する値を返します。


EINVAL

説明:

attr または protocol に指定した値は無効です。


EPERM

説明:

呼び出し元はこの操作を行うための権限を持っていません。

mutex 属性のプロトコルの取得

pthread_mutexattr_getprotocol(3C) は、mutex 属性オブジェクトのプロトコル属性を取得します。

pthread_mutexattr_getprotocol の構文

#include <pthread.h> 
int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict attr, 
int *restrict protocol);

attr は、先の pthread_mutexattr_init() の呼び出しによって作成された mutex 属性オブジェクトを指します。

protocol には、次のプロトコル属性のうちいずれか 1 つが含まれています。 PTHREAD_PRIO_NONEPTHREAD_PRIO_INHERIT、または PTHREAD_PRIO_PROTECT です。これらはヘッダー <pthread.h> で定義されています。

pthread_mutexattr_getprotocol の戻り値

pthread_mutexattr_getprotocol() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。

次のどちらかの条件が検出されると、pthread_mutexattr_getprotocol() は失敗し、条件に対応する値を返します。


EINVAL

説明:

attr で指定された値が NULL か、attr または protocol で指定された値が無効です。


EPERM

説明:

呼び出し元はこの操作を行うための権限を持っていません。

mutex 属性の優先順位上限の設定

pthread_mutexattr_setprioceiling(3C) は、mutex 属性オブジェクトの優先順位上限属性を設定します。

pthread_mutexattr_setprioceiling の構文

#include <pthread.h> 
int pthread_mutexattr_setprioceiling(pthread_mutexatt_t *attr, int prioceiling);

attr は、先の pthread_mutexattr_init() の呼び出しによって作成された mutex 属性オブジェクトを指します。

prioceiling には、初期化された mutex の優先順位上限を指定します。この上限は、mutex によって保護されている重要領域が実行される最小の優先レベルを定義します。prioceiling は、SCHED_FIFO によって定義される優先順位の最大範囲内にあります。優先順位が逆転しないように、特定の mutex をロックするすべてのスレッドの中でもっとも高い優先順位と同じかまたはそれを上回る優先順位を prioceiling として設定します。

pthread_mutexattr_setprioceiling の戻り値

pthread_mutexattr_setprioceiling() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。

次のどちらかの条件が検出されると、pthread_mutexattr_setprioceiling() は失敗し、対応する値を返します。


EINVAL

説明:

attr で指定された値が NULL または無効であるか、prioceiling が無効です。


EPERM

説明:

呼び出し元はこの操作を行うための権限を持っていません。

mutex 属性の優先順位上限の取得

pthread_mutexattr_getprioceiling(3C) は、mutex 属性オブジェクトの優先順位上限属性を取得します。

pthread_mutexattr_getprioceiling の構文

#include <pthread.h> 
int pthread_mutexattr_getprioceiling(const pthread_mutexatt_t *restrict attr, 
           int *restrict prioceiling);

attr は、先の pthread_mutexattr_init() の呼び出しによって作成された属性オブジェクトを指します。

pthread_mutexattr_getprioceiling() は、初期化された mutex の優先順位上限を prioceiling で返します。この上限は、mutex によって保護されている重要領域が実行される最小の優先レベルを定義します。prioceiling は、SCHED_FIFO によって定義される優先順位の最大範囲内にあります。優先順位が逆転しないように、特定の mutex をロックするすべてのスレッドの中でもっとも高い優先順位と同じかまたはそれを上回る優先順位を prioceiling として設定します。

pthread_mutexattr_getprioceiling の戻り値

pthread_mutexattr_getprioceiling() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。

次のどちらかの条件が検出されると、pthread_mutexattr_getprioceiling() は失敗し、対応する値を返します。


EINVAL

説明:

attr で指定された値が NULL です。


EPERM

説明:

呼び出し元はこの操作を行うための権限を持っていません。

mutex の優先順位上限の設定

pthread_mutexattr_setprioceiling(3C) は、mutex の優先順位上限を設定します。

pthread_mutex_setprioceiling の構文

#include <pthread.h> 
int pthread_mutex_setprioceiling(pthread_mutex_t *restrict mutex, 
          int prioceiling, int *restrict old_ceiling);

pthread_mutex_setprioceiling()mutex の優先順位上限、つまり prioceiling を変更します。pthread_mutex_setprioceiling() は、mutex のロックが解除されている場合 mutex をロックするか、mutex を正常にロックできるようになるまでブロックして、mutex の優先順位上限を変更し、mutex を開放します。()mutex をロックするプロセスでは、優先順位保護プロトコルを守る必要はありません。

pthread_mutex_setprioceiling() が正常に終了すると、優先順位上限の以前の値が old_ceiling で返されます。pthread_mutex_setprioceiling() が失敗すると、mutex の優先順位上限は元のままになります。

pthread_mutex_setprioceiling の戻り値

pthread_mutex_setprioceiling() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。

次のいずれかの条件が検出されると、pthread_mutex_setprioceiling() は失敗し、対応する値を返します。


EINVAL

説明:

prioceiling で要求された優先順位が範囲外です。


EINVAL

説明:

mutex が、THREAD_PRIO_PROTECT の値を持つ protocol 属性で初期化されていませんでした。


EPERM

説明:

呼び出し元はこの操作を行うための権限を持っていません。

mutex の優先順位上限の取得

pthread_mutexattr_getprioceiling(3C) は、mutex の優先順位上限を取得します。

pthread_mutex_getprioceiling の構文

#include <pthread.h> 
int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict mutex, 
          int *restrict prioceiling);

pthread_mutex_getprioceiling() は、mutex の優先順位上限、つまり prioceiling を返します。

pthread_mutex_getprioceiling の戻り値

pthread_mutex_getprioceiling() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。

次の条件が検出されると、pthread_mutexatt_getprioceiling() は失敗し、対応する値を返します。

次のいずれかの条件が検出されると、pthread_mutex_getprioceiling() は失敗し、対応する値を返します。


EINVAL

説明:

mutex で指定された値は現在の既存の mutex を参照していません。


EPERM

説明:

呼び出し元はこの操作を行うための権限を持っていません。

mutex の堅牢度属性の設定

pthread_mutexattr_setrobust_np(3C) は、mutex 属性オブジェクトの堅牢度属性を設定します。

pthread_mutexattr_setrobust_np の構文

#include <pthread.h> 
int pthread_mutexattr_setrobust_np(pthread_mutexattr_t *attr, int *robustness);

注 –

pthread_mutexattr_setrobust_np() が適用されるのは、シンボル _POSIX_THREAD_PRIO_INHERIT が定義されている場合だけです。

Solaris 10 および以前のリリースでは、PTHREAD_MUTEX_ROBUST_NP 属性は、自身も PTHREAD_PRIO_INHERIT プロトコル属性でマークされている mutex にのみ適用できます。この制限は、それ以降の Solaris リリースでは解消されています。


attr は、先の pthread_mutexattr_init() の呼び出しによって作成された mutex 属性オブジェクトを指します。

robustness は、mutex の所有者が (通常はプロセスが異常終了したために) mutex をロック解除しないで終了した場合の動作を定義します。pthread.h に定義可能な robustness の値は、PTHREAD_MUTEX_ROBUST_NP または PTHREAD_MUTEX_STALLED_NP です。デフォルト値は、PTHREAD_MUTEX_STALLED_NP です。

pthread_mutexattr_setrobust_np の戻り値

pthread_mutexattr_setrobust_np() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。

次の条件が検出されると、pthread_mutexattr_setrobust_np() は失敗する可能性があります。


EINVAL

説明:

attr または robustness で指定された値は無効です。

mutex の堅牢度属性の取得

pthread_mutexattr_getrobust_np(3C) は、mutex 属性オブジェクトの堅牢度属性を取得します。

pthread_mutexattr_getrobust_np の構文

#include <pthread.h> 
int pthread_mutexattr_getrobust_np(const pthread_mutexattr_t *attr, int *robustness);

attr は、先の pthread_mutexattr_init() の呼び出しによって作成された mutex 属性オブジェクトを指します。

robustness は、mutex 属性オブジェクトの堅牢度属性の値です。

pthread_mutexattr_getrobust_np の戻り値

pthread_mutexattr_getrobust_np() は、正常終了時に 0 を返します。それ以外の戻り値は、エラーが発生したことを示します。

次の条件が検出されると、pthread_mutexattr_getrobust_np() は失敗する可能性があります。


EINVAL

説明:

attr または robustness で指定された値は無効です。