1PTHREAD_ATFORK(3P) POSIX Programmer's Manual PTHREAD_ATFORK(3P)
2
3
4
6 This manual page is part of the POSIX Programmer's Manual. The Linux
7 implementation of this interface may differ (consult the corresponding
8 Linux manual page for details of Linux behavior), or the interface may
9 not be implemented on Linux.
10
12 pthread_atfork — register fork handlers
13
15 #include <pthread.h>
16
17 int pthread_atfork(void (*prepare)(void), void (*parent)(void),
18 void (*child)(void));
19
21 The pthread_atfork() function shall declare fork handlers to be called
22 before and after fork(), in the context of the thread that called
23 fork(). The prepare fork handler shall be called before fork() pro‐
24 cessing commences. The parent fork handle shall be called after fork()
25 processing completes in the parent process. The child fork handler
26 shall be called after fork() processing completes in the child process.
27 If no handling is desired at one or more of these three points, the
28 corresponding fork handler address(es) may be set to NULL.
29
30 If a fork() call in a multi-threaded process leads to a child fork han‐
31 dler calling any function that is not async-signal-safe, the behavior
32 is undefined.
33
34 The order of calls to pthread_atfork() is significant. The parent and
35 child fork handlers shall be called in the order in which they were
36 established by calls to pthread_atfork(). The prepare fork handlers
37 shall be called in the opposite order.
38
40 Upon successful completion, pthread_atfork() shall return a value of
41 zero; otherwise, an error number shall be returned to indicate the
42 error.
43
45 The pthread_atfork() function shall fail if:
46
47 ENOMEM Insufficient table space exists to record the fork handler
48 addresses.
49
50 The pthread_atfork() function shall not return an error code of
51 [EINTR].
52
53 The following sections are informative.
54
56 None.
57
59 The original usage pattern envisaged for pthread_atfork() was for the
60 prepare fork handler to lock mutexes and other locks, and for the par‐
61 ent and child handlers to unlock them. However, since all of the rele‐
62 vant unlocking functions, except sem_post(), are not async-signal-safe,
63 this usage results in undefined behavior in the child process unless
64 the only such unlocking function it calls is sem_post().
65
67 There are at least two serious problems with the semantics of fork() in
68 a multi-threaded program. One problem has to do with state (for exam‐
69 ple, memory) covered by mutexes. Consider the case where one thread has
70 a mutex locked and the state covered by that mutex is inconsistent
71 while another thread calls fork(). In the child, the mutex is in the
72 locked state (locked by a nonexistent thread and thus can never be
73 unlocked). Having the child simply reinitialize the mutex is unsatis‐
74 factory since this approach does not resolve the question about how to
75 correct or otherwise deal with the inconsistent state in the child.
76
77 It is suggested that programs that use fork() call an exec function
78 very soon afterwards in the child process, thus resetting all states.
79 In the meantime, only a short list of async-signal-safe library rou‐
80 tines are promised to be available.
81
82 Unfortunately, this solution does not address the needs of multi-
83 threaded libraries. Application programs may not be aware that a multi-
84 threaded library is in use, and they feel free to call any number of
85 library routines between the fork() and exec calls, just as they always
86 have. Indeed, they may be extant single-threaded programs and cannot,
87 therefore, be expected to obey new restrictions imposed by the threads
88 library.
89
90 On the other hand, the multi-threaded library needs a way to protect
91 its internal state during fork() in case it is re-entered later in the
92 child process. The problem arises especially in multi-threaded I/O
93 libraries, which are almost sure to be invoked between the fork() and
94 exec calls to effect I/O redirection. The solution may require locking
95 mutex variables during fork(), or it may entail simply resetting the
96 state in the child after the fork() processing completes.
97
98 The pthread_atfork() function was intended to provide multi-threaded
99 libraries with a means to protect themselves from innocent application
100 programs that call fork(), and to provide multi-threaded application
101 programs with a standard mechanism for protecting themselves from
102 fork() calls in a library routine or the application itself.
103
104 The expected usage was that the prepare handler would acquire all mutex
105 locks and the other two fork handlers would release them.
106
107 For example, an application could have supplied a prepare routine that
108 acquires the necessary mutexes the library maintains and supplied child
109 and parent routines that release those mutexes, thus ensuring that the
110 child would have got a consistent snapshot of the state of the library
111 (and that no mutexes would have been left stranded). This is good in
112 theory, but in reality not practical. Each and every mutex and lock in
113 the process must be located and locked. Every component of a program
114 including third-party components must participate and they must agree
115 who is responsible for which mutex or lock. This is especially problem‐
116 atic for mutexes and locks in dynamically allocated memory. All mutexes
117 and locks internal to the implementation must be locked, too. This pos‐
118 sibly delays the thread calling fork() for a long time or even indefi‐
119 nitely since uses of these synchronization objects may not be under
120 control of the application. A final problem to mention here is the
121 problem of locking streams. At least the streams under control of the
122 system (like stdin, stdout, stderr) must be protected by locking the
123 stream with flockfile(). But the application itself could have done
124 that, possibly in the same thread calling fork(). In this case, the
125 process will deadlock.
126
127 Alternatively, some libraries might have been able to supply just a
128 child routine that reinitializes the mutexes in the library and all
129 associated states to some known value (for example, what it was when
130 the image was originally executed). This approach is not possible,
131 though, because implementations are allowed to fail *_init() and
132 *_destroy() calls for mutexes and locks if the mutex or lock is still
133 locked. In this case, the child routine is not able to reinitialize the
134 mutexes and locks.
135
136 When fork() is called, only the calling thread is duplicated in the
137 child process. Synchronization variables remain in the same state in
138 the child as they were in the parent at the time fork() was called.
139 Thus, for example, mutex locks may be held by threads that no longer
140 exist in the child process, and any associated states may be inconsis‐
141 tent. The intention was that the parent process could have avoided this
142 by explicit code that acquires and releases locks critical to the child
143 via pthread_atfork(). In addition, any critical threads would have
144 needed to be recreated and reinitialized to the proper state in the
145 child (also via pthread_atfork()).
146
147 A higher-level package may acquire locks on its own data structures
148 before invoking lower-level packages. Under this scenario, the order
149 specified for fork handler calls allows a simple rule of initialization
150 for avoiding package deadlock: a package initializes all packages on
151 which it depends before it calls the pthread_atfork() function for
152 itself.
153
154 As explained, there is no suitable solution for functionality which
155 requires non-atomic operations to be protected through mutexes and
156 locks. This is why the POSIX.1 standard since the 1996 release requires
157 that the child process after fork() in a multi-threaded process only
158 calls async-signal-safe interfaces.
159
161 The pthread_atfork() function may be formally deprecated (for example,
162 by shading it OB) in a future version of this standard.
163
165 atexit(), exec, fork()
166
167 The Base Definitions volume of POSIX.1‐2017, <pthread.h>, <sys_types.h>
168
170 Portions of this text are reprinted and reproduced in electronic form
171 from IEEE Std 1003.1-2017, Standard for Information Technology -- Por‐
172 table Operating System Interface (POSIX), The Open Group Base Specifi‐
173 cations Issue 7, 2018 Edition, Copyright (C) 2018 by the Institute of
174 Electrical and Electronics Engineers, Inc and The Open Group. In the
175 event of any discrepancy between this version and the original IEEE and
176 The Open Group Standard, the original IEEE and The Open Group Standard
177 is the referee document. The original Standard can be obtained online
178 at http://www.opengroup.org/unix/online.html .
179
180 Any typographical or formatting errors that appear in this page are
181 most likely to have been introduced during the conversion of the source
182 files to man page format. To report such errors, see https://www.ker‐
183 nel.org/doc/man-pages/reporting_bugs.html .
184
185
186
187IEEE/The Open Group 2017 PTHREAD_ATFORK(3P)