You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

子进程中注册SIGTERM信号处理器无效,如何解决?

问题原因与跨平台解决方案

为什么"terminate callback"不打印?

Windows平台

Windows系统中,multiprocessing.Process.terminate()通过系统API TerminateProcess 强制终止进程,不会发送任何信号。同时Windows原生没有SIGTERM信号,signal.signal(signal.SIGTERM, ...)只是一个无效占位符,信号处理器根本不会被触发。

macOS(Unix-like)

虽然terminate()会发送SIGTERM信号,但存在两个可能的问题:

  1. 子进程的print输出存在缓冲,导致内容还没来得及刷新到控制台,进程就已经终止。
  2. 父进程没有等待子进程退出,子进程的输出无法被完整捕获。

跨平台解决方案

我们用multiprocessing.Event实现跨平台的优雅退出通知,同时保留Unix平台的信号处理逻辑,确保回调能被执行。修改后的代码如下:

import signal
import traceback
from multiprocessing import Process, Event
from time import sleep

class GracefulExitHandler:
    def __init__(self, job, exit_event=None):
        self.job = job
        self.exit_event = exit_event
        # 为Unix-like平台注册SIGTERM处理器
        try:
            self.prev_signal = signal.signal(signal.SIGTERM, self._handle_signal)
            print("registered SIGTERM signal handler")
        except ValueError:
            # Windows不支持SIGTERM信号处理,直接跳过
            print("SIGTERM handler not supported on this platform")

    def _handle_signal(self, _signo, _stack_frame):
        self.job()
        if self.prev_signal:
            self.prev_signal(_signo, _stack_frame)
        if self.exit_event:
            self.exit_event.set()

    def wait_for_exit(self, timeout=None):
        if self.exit_event:
            self.exit_event.wait(timeout)


def process(exit_event):
    def terminate_callback():
        print("terminate callback")
        # 强制刷新输出,避免缓冲导致内容无法显示
        print.flush()

    handler = GracefulExitHandler(terminate_callback, exit_event)
    # 循环检测退出信号,替代原有的sleep(10)
    while not exit_event.is_set():
        sleep(0.1)
    print("done")
    print.flush()


if __name__ == '__main__':
    while True:
        try:
            exit_event = Event()
            p = Process(target=process, args=(exit_event,))
            p.start()
            sleep(2)
            # 先通知子进程优雅退出
            exit_event.set()
            # 针对Unix平台发送SIGTERM(可选,Event已能通知退出)
            try:
                p.terminate()
            except NotImplementedError:
                # Windows下terminate是强制杀进程,先等待子进程处理回调
                pass
            print("terminate called")
            # 等待子进程退出,确保输出完全打印
            p.join()

        except Exception as e:
            traceback.print_exc()
    print("Done")

关键修改点

  • 跨平台退出通知:用Event替代信号,Windows子进程通过检测Event状态主动执行回调并退出。
  • 输出缓冲处理:在print后调用print.flush(),确保内容立即输出到控制台。
  • 父进程等待:调用p.join()等待子进程退出,避免子进程输出被截断。
  • Unix信号兼容:保留SIGTERM处理器,兼容Unix平台下其他方式发送的终止信号。

内容的提问来源于stack exchange,提问作者Ofek Ron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 08:20:27