PTHREAD_MUTEX

Section: C Library Functions (3)
Updated: LinuxThreads
Index JM Home Page

 

名前

pthread_mutex_init, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, pthread_mutex_destroy - mutex の操作

 

書式

#include <pthread.h>

pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

int pthread_mutex_lock(pthread_mutex_t *mutex));

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

int pthread_mutex_destroy(pthread_mutex_t *mutex);

 

説明

mutex は、排他制御 (MUTual EXclusion) の仕組みであり、共有データの同時更新 からの保護、クリティカルセクション (critical section) や モニタの実装などに使われる。

mutex は二つの状態を取りうる。それは、アンロック状態(どのスレッドにも 保有されていない)とロック状態(一つのスレッドに保有されている)である。 二つの異なるスレッドが同時に一つの mutex を保有することはない。既に他の スレッドによってロックされた mutex をロックしようとするスレッドは、保有 側のスレッドが先にその mutex をアンロックするまで実行を停止させられる。

pthread_mutex_init は mutex が指す mutex オブジェクトを、 mutexattr で指定された mutex 属性オブジェクトに従って初期化する。 mutexattr が NULL, ならば、デフォルトの属性がこのかわりに使われる。

LinuxThreads の実装はただ一つの属性 mutex kind だけに対応している。この属性は、「速い」(``fast'')、 「再帰的な」(``recursive'')、または 「エラー検査を行なう」(``error checking'')のいずれかを 指定するものである。 mutex の種別(kind)は、その mutex を既に保有しているスレッドが、 それを再びロックできるかどうかを決定する。 デフォルトの種別は「速い」である。mutex 属性のより詳しい情報は、 pthread_mutexattr_init(3) を見よ。

pthread_mutex_t 型の変数は、(速い mutex に対する)定数 PTHREAD_MUTEX_INITIALIZER と、(再帰的 mutex に対する) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP および、(エラー検査を行なう mutex に対する) PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP で、静的に初期化することもできる。

pthread_mutex_lock は、与えられた mutex をロックする。mutex が現在ロックされていなければ、 それはロックされ、呼び出しスレッドによって所有される。この場合 pthread_mutex_lock は直ちに返る。mutex が他のスレッドによって既にロックされていたのならば、 pthread_mutex_lock は mutex がアンロックされるまで呼び出しスレッドの実行を停止させる。

mutex が呼び出し側のスレッドにより既にロックされている場合には、 pthread_mutex_lock の振舞いは、mutex の種別に依存する。mutex の種別が「速い」であれば、 呼び出しスレッドは mutex がアンロックされるまで実行を停止する。 従って事実上呼び出しスレッドのデッドロックを引き起こす。 mutex の種別が「エラーをチェックする」であれば、 pthread_mutex_lock はエラーコード EDEADLK とともに直ちに戻る。mutex の種別が「再帰的」ならば、 pthread_mutex_lock は成功し直ちに戻る。この際、呼び出しスレッドが、その mutex を ロックした回数を記録する。この mutex がアンロック状態に戻るには、 同数の pthread_mutex_unlock 操作が実行されねばならない。

pthread_mutex_trylock は pthread_mutex_lock と同様に振舞うが、mutex が既に他のスレッドによって (あるいは、「速い」 mutex の場合、呼び出しスレッドによって) ロックされている場合、呼び出しスレッドをブロックしない。 かわりに、 pthread_mutex_trylock はエラーコード EBUSY で直ちに戻る。

pthread_mutex_unlock は、与えられた mutex をアンロックする。 pthread_mutex_unlock の開始時点で、この mutex は呼び出しスレッドによりロックされ 所有されているものと仮定される。
 mutex が「速い」種別のものならば、 pthread_mutex_unlock は常にそれをアンロック状態に戻す。それが「再帰的な」種別ならば、
 mutex のロック計数(この mutex に対して pthread_mutex_lock 操作が呼び出しスレッドで実行された回数) を一つ減らし、この計数がゼロになった時に、初めて mutex が 実際にアンロックされる。

「エラーを検査する」mutex に対しては、 pthread_mutex_unlock は実行時に実際に、mutex が開始時点でロックされているか、 また、それは現在 pthread_mutex_unlock を呼んでいるのと同じスレッドによってロックされたかどうか、を検査する。 これらの条件が満たされない場合には、エラーコードが返され、mutex は 不変のままにされる。「速い」mutex と「再帰的な」mutex はこのような チェックを行なわなず、よって、ロックされた mutex を所有者以外の スレッドによってアンロックすることを可能にしている。これは、移植性の ない振舞いであり、これに依存するようなことはすべきでない。

pthread_mutex_destroy は、mutex オブジェクトを破壊し、それが保持している可能性のある 資源を開放する。mutex は関数の開始時点でアンロックされていなければ ならない。LinuxThreads の実装では、いかなる資源も mutex オブジェクトに 付随していない。故に pthread_mutex_destroy は実際のところ、mutex がアンロックされているかどうかを検査する 以外のことは何もしない。

 

取り消し

いかなる mutex 関数も取り消しポイントではない。 pthread_mutex_lock でさえも、それが任意の時間スレッドの実行を停止させうるという 事実にも関わらず、取り消しポイントではない。これにより、取り消し ポイントにおける mutex の状態は予測可能となり、取り消しハンドラが、 スレッドの実行停止以前にアンロックされる必要のある mutex まさにそれ のみを、正確にアンロックすることを可能にしている。この結果、遅延 取り消しを用いるスレッドは、決して余計な時間 mutex を所有することはない。

 

非同期シグナルに対する安全性

mutex 関数は非同期シグナルに対して安全ではない。これの 意味するところは、それらはシグナルハンドラから呼ぶべきではない、 ということである。特に pthread_mutex_lock または pthread_mutex_unlock のシグナルハンドラからの呼び出しは、呼び出しスレッドをデッド ロックさせる恐れがある。

 

返り値

pthread_mutex_init は、常に 0 を返す。他の mutex 関数は、成功すれば 0 を返し、 エラーでは非ゼロのエラーコードを返す。

 

エラー

pthread_mutex_lock はエラーの際、次のエラーコードを返す:

EINVAL
mutex が適切に初期化されていない。
EDEADLK
mutex は既に呼び出しスレッドによりロックされている。 (「エラー検査を行なう」 mutexes のみ)

pthread_mutex_trylock はエラーの際、次のエラーコードを返す:

EBUSY
現在ロックされているので mutex を取得できない。
EINVAL
mutex が適切に初期化されていない。

pthread_mutex_unlock はエラーの際、次のエラーコードを返す:

EINVAL
mutex が適切に初期化されていない。
EPERM
呼び出しスレッドは mutex を所有していない。(「エラーを検査する」 mutex のみ)

pthread_mutex_destroy はエラーの際、次のエラーコードを返す:

EBUSY
mutex は現在ロックされている。

 

著者

Xavier Leroy <Xavier.Leroy@inria.fr>

 

関連項目

pthread_mutexattr_init(3), pthread_mutexattr_setkind_np(3), pthread_cancel(3).

 

例

共有される大域変数 x は mutex により次のように保護される:


int x;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

全ての x へのアクセスとその変更は pthread_mutex_lock と pthread_mutex_unlock によって、次のように囲まれていなければならない:


pthread_mutex_lock(&mut);
/* x の操作 */
pthread_mutex_unlock(&mut);

[訳注] glibc-linuxthreads の最新のドキュメントは Texinfo 形式で提供されている。 上の記述は glibc-linuxthreads-2.2 以降では正しくない。 以下は glibc-linuxthreads-2.3.1 の Texinfo ファイルからの引用である。 種別 (kind) が型 (type) に変更されている。

LinuxThreads 実装はただ 1 つの mutex 属性に対応している。 それは mutex 型 (mutex type) で、 「速い (fast) 」、「再帰的な (recursive) 」、 「時刻情報つき (timed) 」、「エラー検査を行なう (error checking) 」の いずれかである。 mutex 型は、 あるスレッドが自分自身ですでに保持している mutex をロックできるかどうかを 決定する。 デフォルトの mutex 型は「時刻情報つき (timed) 」である。

pthread_mutex_t 型の変数は、定数 PTHREAD_MUTEX_INITIALIZER ( 時刻情報つき (timed) mutex 用 ) 、 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ( 再帰的な (recursive) mutex 用 ) 、 PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP ( 速い (fast) mutex 用 ) 、 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP ( エラー検査を行なう (error checking) mutex 用 ) を用いて 静的に初期化することもできる。


関連キーワード

mutex   スレッド   ロック   アンロック   検査   種別   pthread   エラーコード   再帰   属性   初期化   保有   停止   取り消し   操作   実装   所有   LinuxThreads   fast   recursive   checking   変数   開始   時点   実際

Linux マニュアル 一覧

関連するコマンド・関数

pthread_mutex_destroy.3   pthread_mutex_init.3   pthread_mutex_trylock.3   pthread_mutex_unlock.3   pthread_mutexattr_destroy.3   pthread_mutexattr_getkind_np.3
 

Index

名前
書式
説明
取り消し
非同期シグナルに対する安全性
返り値
エラー
著者
関連項目
例

This document was created by man2html, using the manual pages.
Time: 04:38:47 GMT, October 11, 2026