terminates. With pthread_atfork you supply three separate handler addresses. The
|If you write a subsystem that uses mutexes and does not establish fork handlers,then that subsystem will not function correctly in a child process after a fork.
Normally a
The
Your fork handlers are only as good as everyone else's fork handlers.
The system will run all
If you use an ANSI C library that doesn't supply fork handlers to prepare those mutexes properly for a fork, for example, then, sometimes, you may find that
your child process hangs when it calls printf, because another thread in the parent process had the mutex locked when your thread called fork. There's often nothing you can do about this type of problem except to file a problem report against the system. These mutexes are usually private to the library, and aren't visible to your code — you can't lock them in your
The program atfork.c shows the use of fork handlers. When run with no argument, or with a nonzero argument, the program will install fork handlers. When run with a zero argument, such as atfork 0, it will not.
With fork handlers installed, the result will be two output lines reporting the result of the fork call and, in parentheses, the pid of the current process. Without fork handlers, the child process will be created while the initial thread owns the mutex. Because the initial thread does not exist in the child, the mutex cannot be unlocked, and the child process will hang — only the parent process will print its message.
13-25 Function fork_prepare is the
31-42 Function fork_parent is the
48-60 Function fork_child is the
65-91 After creating a child process, which will continue executing the thread_ routine code, the thread_routine function locks the mutex. When run with fork handlers, the fork call will be blocked (when the
108-123 The main program locks the mutex before creating the thread that will fork. It then sleeps for several seconds, to ensure that the thread will be able to call fork while the mutex is locked, and then unlocks the mutex. The thread running thread_routine will always succeed in the parent process, because it will simply block until main releases the lock.
However, without the fork handlers, the child process will be created while the mutex is locked. The thread (main) that locked the mutex does not exist in the child, and cannot unlock the mutex in the child process. Mutexes can be unlocked
in the child only if they were locked by the thread that called fork — and fork handlers provide the best way to ensure that.
¦ atfork.c
1 #include <sys/types.h>
2 #include <pthread.h>
3 #include <sys/wait.h>
4 #include 'errors.h'
5
6 pid_t self_pid; /* pid of current process */
7 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
8
9 /*
10 * This routine will be called prior to executing the fork,
11 * within the parent process.
12 */
13 void fork_prepare (void)
14 {
15 int status;
16
17 /*
18 * Lock the mutex in the parent before creating the child,
19 * to ensure that no other thread can lock it (or change any
20 * associated shared state) until after the fork completes.
21 */
22 status = pthread_mutex_lock (&mutex);
23 if (status != 0)
24 err_abort (status, 'Lock in prepare handler');
25 }
26
27 /*
28 * This routine will be called after executing the fork, within
29 * the parent process
30 */
31 void fork_parent (void)
32 {
33 int status;
34
35 /*
36 * Unlock the mutex in the parent after the child has been
37 * created.