The Linux documentation for sleep
lists the following attributes at the bottom:
┌──────────┬───────────────┬─────────────────────────────┐
│Interface │ Attribute │ Value │
├──────────┼───────────────┼─────────────────────────────┤
│sleep() │ Thread safety │ MT-Unsafe sig:SIGCHLD/linux │
└──────────┴───────────────┴─────────────────────────────┘
That sig:SIGCHLD/linux
is important in this context. As per here, it's explained as follows (my emphasis):
sig
: Functions marked with sig as a MT-Safety issue may temporarily install a signal handler for internal purposes, which may interfere with other uses of the signal, identified after a colon.
This safety problem can be worked around by ensuring that no other uses of the signal will take place for the duration of the call. Holding a non-recursive mutex while calling all functions that use the same temporary signal; blocking that signal before the call and resetting its handler afterwards is recommended.
Blocking a signal can be done with the sigprocmask
call, such as with:
// Need signal.h for this stuff.
sigset_t mask;
if ((sigemptyset(&mask) == -1) || (sigaddset(&mask, SIGCHLD) == -1)) {
// handle failure here.
}
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
// handle failure here.
}
sleep(3);
// Probably need to re-establish CHLD signal handler as well as unmasking.
if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) {
// handle failure here.
}