1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
import os
import sys
import time
import signal
import multiprocessing
def print_signal(signum):
def new_handler(signum, frame):
nonlocal old_handler
pid = os.getpid()
print(f"[PID {pid}] SIGNAL {signum}", flush=True)
if old_handler is None:
old_handler = signal.SIG_IGN
signal.signal(signum, old_handler)
os.kill(pid, signum)
try:
old_handler = signal.signal(signum, new_handler)
except (OSError, AttributeError, ValueError, RuntimeError):
pass
def reg_signals():
print_signal(signal.SIGINT)
print_signal(signal.SIGTERM)
print_signal(signal.SIGHUP)
def main(sleep_time):
reg_signals()
p = multiprocessing.current_process()
s = "daemonic" if p.daemon else "non-daemonic"
print("[Parent] Starting:", p.name, p.pid, s, flush=True)
try:
time.sleep(sleep_time)
except BaseException as e:
print("[Parent] Exception :", str(e), s, flush=True)
raise
else:
print("[Parent] Finished normally:", p.name, p.pid, s, flush=True)
finally:
print("[Parent] Exiting :", p.name, p.pid, s, flush=True)
sys.stdout.flush()
if __name__ == "__main__":
d = multiprocessing.Process(name="daemon", target=main, args=(10,))
d.daemon = True
n = multiprocessing.Process(name="non-daemon", target=main, args=(15,))
n.daemon = False
d.start()
n.start()
time.sleep(2)
print(f"[Parent] Send SIGTERM to daemon {d.pid} and wait for non-daemon {n.pid}")
|