I am trying to wait in python until either
There is a function os.sigwait
that seems to fit this purpose, but I cannot get it to return on a forked child process exit by calling os.sigwait({signal.SIGCHLD})
- this ends in a deadlock.
What I tried:
#!/usr/bin/env python3
import signal
import os
import time
if __name__ == '__main__':
pid = None # initial value
try:
pid = os.fork() # method is available only on UNIX platforms
if pid != 0: # parent
# Wait for child exit or SIGINT
# (should also work for signals other than SIGINT)
signal.sigwait({signal.SIGCHLD, signal.SIGINT})
print("Got signal")
# never reaching this statement by child exit
else: # child
time.sleep(3)
finally:
if pid is None: # fork failed
pass
elif pid == 0:
print("\nChild cleaning up")
else:
print("\nParent cleaning up")
Pulling the answer out of comments:
The solution is to call pthread_sigmask(SIG_BLOCK, {SIGCHLD, SIGINT})
before calling sigwait()
.
The sigwait
family of functions are designed to accept pending signals, rather than to deliver as do sigaction
and signal
. For this to work properly, the desired signals need to be masked (blocked) before they can be reliably accepted. Indeed, in the POSIX specification, calling sigwait
on a set of signals without first blocking those signals is undefined