Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_all
名前
pthread_atfork - fork(2) の際に呼び出されるハンドラを登録する
書式
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
説明
pthread_atfork は fork(2) によって新しいプロセスが生成される際、その直前と直後に呼び出され る ハンドラ関数を登録する。 prepare ハンドラは、新しいプロセスが生成される直前に親プロセス から 呼び出される。 parent ハンドラは、 fork(2) がリターンする直前に親プロセスから呼び出さ れる。 child ハンドラは fork(2) が返る直前に子プロセスから呼び出される。 prepare, parent および child の三つのハンドラのうちの一つまたは複数に NULL を与えることが できるが、これは対応する時点でいかなるハンドラをも 呼び出す必要がないことを意味する。 pthread_atfork は複数のハンドラの組合せを登録するために複数回 呼び出すことが可能である。 fork(2) の時点で複数の prepare ハンドラは LIFO 順で呼び出される( pthread_atfork で最後に加 えられたものが fork の前に最初に呼び出される)。 他方、 parent と child は FIFO 順で呼び出 される (最初に加えられたものが最初に呼び出される)。 pthread_atfork の目的を理解するために、 fork(2) は、現在ロック状態にある mutex も含め て、呼び出したスレッドのみの メモリ空間全体を複製することを思い出そう。つまり、他のスレッ ドは 子プロセスでは実行されていないのである。従って、 fork を呼び出したスレッド以外のス レッドによって mutex がロックされている のならば、その mutex は子プロセスの中で永遠にロッ クされたままであり、 子プロセスの実行をブロックする可能性がある。 これを避けるためには、 pthread_atfork で次のようなハンドラを登録すれば良いだろう: prepare ハンドラが大域的な mutex を(ロックする際の順序で)ロックし、 parent と child がそれらを(逆の順に)アンロックす る。 または、 prepare と parent を NULL に設定し、 child を大域的な mutex に対して pthread_mutex_init を呼び出す関数に設定しても良いだろう。
返り値
pthread_atfork は成功すれば 0 を返し、エラーがあれば非ゼロのエラーコードを返す。
エラー
ENOMEM ハンドラを登録するのにメモリが足りない。
著者
Xavier Leroy <Xavier.Leroy@inria.fr>
関連項目
fork(2), pthread_mutex_lock(3), pthread_mutex_unlock(3). [訳注] glibc-linuxthreads の最新のドキュメントは Texinfo形式で提供されている。 以下は glibc-linuxthreads-2.3.1 の Texinfo ファイルからの引用である。 pthread_atfork の目的を理解するために、 fork が現在ロック状態にある mutex も含めたメモリ空 間全体を、 しかし呼び出しスレッドだけを複製することを思い出してほしい。 つまり、他のスレッ ドは子プロセスでは実行されない。 mutex は fork の後は使うことができず、子プロセスで pthread_mutex_init を使って初期化されなければならない。 これは現在の実装の制限で、将来の バージョンでも存在するかもしれないし、 存在しないかもしれない。 これを避けるためには、 pthread_atfork で次のようなハンドラを登録すればよい: prepare ハンド ラで mutex を (ロックする際の順序で) ロックし、 parent ハンドラで mutex をロック解除する。 child ハンドラでは pthread_mutex_init を使用して mutex を初期化しなければならない。 条件変 数などの他の同期オブジェクトについても同様である。 グローバル mutex を fork の前にロックすると、 他のスレッドはすべて、それらのグローバル mutex で保護される コードのクリティカル領域から締め出される。したがって fork が親プロセス のアドレス空間のスナップショットを取ると、 そのスナップショットは有効で安定したデータをコ ピーする。 子プロセスで同期オブジェクトを初期化することで 親プロセスのスレッドサブシステム に由来するものが適切に清められることが保証される。 例えば、 mutex は獲得を待つスレッドの待 ちキューを引き継ぐが、 この待ちキューは子プロセスでは意味を持たない。 mutex を初期化するこ とでこのことに対処する。 LinuxThreads PTHREAD_ATFORK(3)