这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions src/helperFunctions/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from concurrent.futures import ThreadPoolExecutor
from contextlib import suppress
from multiprocessing import Pipe, Process
from signal import SIGTERM
from threading import Thread
from typing import TYPE_CHECKING

Expand Down Expand Up @@ -105,22 +104,26 @@ def exception(self) -> tuple[Exception, str] | None:
return self._exception


def terminate_process_and_children(process: Process) -> None:
def terminate_process_and_children(process: Process | psutil.Process):
"""
Terminate a process and all of its child processes.
Terminate a process and all of its child processes recursively.

:param process: The process to be terminated.
"""
process.terminate()
_terminate_orphans(process)
process.join()


def _terminate_orphans(process):
with suppress(psutil.NoSuchProcess):
parent = psutil.Process(process.pid)
for child in parent.children(recursive=True):
child.send_signal(SIGTERM)
try:
if isinstance(process, Process):
process = psutil.Process(process.pid)
children = process.children(recursive=False)
process.terminate() # try to send SIGTERM first before SIGKILL
with suppress(psutil.TimeoutExpired):
process.wait(timeout=5) # give the process and its children some time to exit gracefully
for child in children:
terminate_process_and_children(child) # make sure all child processes also stop

if process.is_running():
process.kill() # if the process still runs after sending SIGTERM: send SIGKILL
except psutil.NoSuchProcess:
return # the process no longer exists (maybe it exited in the meantime)


def start_single_worker(process_index: int, label: str, function: Callable) -> ExceptionSafeProcess:
Expand Down