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
|
# mypy: allow-untyped-defs
import os
import signal
from threading import Thread
from time import sleep
from typing import Optional
# If this process dies abnormally (e.g. segfault)
# it will not shut down the workers. Instead,
# the workers will have their parent reassigned to the
# init process. This launches a separate thread to
# watch for the worker getting reassigned,
# and cleans it up in this case.
#
# This function cannot be an inner function since otherwise mp_context="spawn" would
# not work for ProcessPoolExecutor since inner functions cannot be pickled.
def _async_compile_initializer(orig_ppid) -> None:
def run() -> None:
while True:
sleep(1)
if orig_ppid != os.getppid():
os.kill(os.getpid(), signal.SIGKILL)
global _watchdog_thread, _original_parent
_original_parent = orig_ppid
_watchdog_thread = Thread(target=run, daemon=True)
_watchdog_thread.start()
# Ignore Ctrl-C (i.e. SIGINT) sent to pool workers to avoid meaningless log spam.
signal.signal(signal.SIGINT, signal.SIG_IGN)
_watchdog_thread: Optional[Thread] = None
_original_parent: Optional[int] = None
def has_parent_changed() -> bool:
return _original_parent != os.getppid()
|