pthread_atforkのヘルプ・マニュアル
日本語 英語
pthread_atfork --help
man pthread_atfork
PTHREAD_ATFORK(3) PTHREAD_ATFORK(3)
名前
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
関連項目
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)
PTHREAD_ATFORK(3P) POSIX Programmer’s Manual PTHREAD_ATFORK(3P)
PROLOG
This manual page is part of the POSIX Programmer’s Manual. The Linux
implementation of this interface may differ (consult the corresponding
Linux manual page for details of Linux behavior), or the interface may
not be implemented on Linux.
NAME
pthread_atfork - register fork handlers
SYNOPSIS
#include
int pthread_atfork(void (*prepare)(void), void (*parent)(void),
void (*child)(void));
DESCRIPTION
The pthread_atfork() function shall declare fork handlers to be called
before and after fork(), in the context of the thread that called
fork(). The prepare fork handler shall be called before fork() process-
ing commences. The parent fork handle shall be called after fork() pro-
cessing completes in the parent process. The child fork handler shall
be called after fork() processing completes in the child process. If
no handling is desired at one or more of these three points, the corre-
sponding fork handler address(es) may be set to NULL.
The order of calls to pthread_atfork() is significant. The parent and
child fork handlers shall be called in the order in which they were
established by calls to pthread_atfork(). The prepare fork handlers
shall be called in the opposite order.
RETURN VALUE
Upon successful completion, pthread_atfork() shall return a value of
zero; otherwise, an error number shall be returned to indicate the
error.
ERRORS
The pthread_atfork() function shall fail if:
ENOMEM Insufficient table space exists to record the fork handler
addresses.
The pthread_atfork() function shall not return an error code of
[EINTR].
The following sections are informative.
EXAMPLES
None.
APPLICATION USAGE
None.
RATIONALE
There are at least two serious problems with the semantics of fork() in
a multi-threaded program. One problem has to do with state (for exam-
ple, memory) covered by mutexes. Consider the case where one thread has
a mutex locked and the state covered by that mutex is inconsistent
while another thread calls fork(). In the child, the mutex is in the
locked state (locked by a nonexistent thread and thus can never be
unlocked). Having the child simply reinitialize the mutex is
unsatisfactory since this approach does not resolve the question about
how to correct or otherwise deal with the inconsistent state in the
child.
It is suggested that programs that use fork() call an exec function
very soon afterwards in the child process, thus resetting all states.
In the meantime, only a short list of async-signal-safe library rou-
tines are promised to be available.
Unfortunately, this solution does not address the needs of multi-
threaded libraries. Application programs may not be aware that a multi-
threaded library is in use, and they feel free to call any number of
library routines between the fork() and exec calls, just as they always
have. Indeed, they may be extant single-threaded programs and cannot,
therefore, be expected to obey new restrictions imposed by the threads
library.
On the other hand, the multi-threaded library needs a way to protect
its internal state during fork() in case it is re-entered later in the
child process. The problem arises especially in multi-threaded I/O
libraries, which are almost sure to be invoked between the fork() and
exec calls to effect I/O redirection. The solution may require locking
mutex variables during fork(), or it may entail simply resetting the
state in the child after the fork() processing completes.
The pthread_atfork() function provides multi-threaded libraries with a
means to protect themselves from innocent application programs that
call fork(), and it provides multi-threaded application programs with a
standard mechanism for protecting themselves from fork() calls in a
library routine or the application itself.
The expected usage is that the prepare handler acquires all mutex locks
and the other two fork handlers release them.
For example, an application can supply a prepare routine that acquires
the necessary mutexes the library maintains and supply child and parent
routines that release those mutexes, thus ensuring that the child gets
a consistent snapshot of the state of the library (and that no mutexes
are left stranded). Alternatively, some libraries might be able to
supply just a child routine that reinitializes the mutexes in the
library and all associated states to some known value (for example,
what it was when the image was originally executed).
When fork() is called, only the calling thread is duplicated in the
child process. Synchronization variables remain in the same state in
the child as they were in the parent at the time fork() was called.
Thus, for example, mutex locks may be held by threads that no longer
exist in the child process, and any associated states may be inconsis-
tent. The parent process may avoid this by explicit code that acquires
and releases locks critical to the child via pthread_atfork(). In
addition, any critical threads need to be recreated and reinitialized
to the proper state in the child (also via pthread_atfork()).
A higher-level package may acquire locks on its own data structures
before invoking lower-level packages. Under this scenario, the order
specified for fork handler calls allows a simple rule of initialization
for avoiding package deadlock: a package initializes all packages on
which it depends before it calls the pthread_atfork() function for
itself.
FUTURE DIRECTIONS
None.
SEE ALSO
atexit(), fork(), the Base Definitions volume of IEEE Std 1003.1-2001,
COPYRIGHT
Portions of this text are reprinted and reproduced in electronic form
from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology
-- Portable Operating System Interface (POSIX), The Open Group Base
Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of
Electrical and Electronics Engineers, Inc and The Open Group. In the
event of any discrepancy between this version and the original IEEE and
The Open Group Standard, the original IEEE and The Open Group Standard
is the referee document. The original Standard can be obtained online
at http://www.opengroup.org/unix/online.html .
IEEE/The Open Group 2003 PTHREAD_ATFORK(3P)