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

Python子进程被terminate终止时未触发atexit函数的问题排查

问题分析与解决方案

为什么子进程被terminate()终止时不会生成foo.txt?

这个问题的核心差异在于Windows系统下进程终止方式的不同:

  • 当你调用proc.terminate()时,Python底层调用的是Windows API的TerminateProcess()函数,这是一种强制终止操作——它会直接杀死目标进程,不给进程执行任何退出清理代码(包括atexit注册的钩子函数)的机会,自然也就不会生成foo.txt。
  • 而你单独运行sub.py并手动终止(比如按Ctrl+C)时,Python会捕获SIGINT中断信号,触发正常的退出流程,此时atexit注册的函数会被执行,所以能正常生成文件。

如何让子进程被终止时仍生成foo.txt?

这里提供两种可靠的解决方案:

方案一:模拟Ctrl+C发送中断信号(最贴近手动终止的行为)

通过给子进程发送CTRL_C_EVENT信号,触发其正常退出流程。需要注意启动子进程时要创建独立的进程组:

## 修改后的mar.py
import os
import subprocess
import time
import signal

print('MASTER PID: ', os.getpid())
# 创建新进程组,确保信号能正确送达子进程
proc = subprocess.Popen(
    ["D:\\Miniconda3\\python.exe", r"C:\\Users\\J\\Desktop\\test\\sub.py"],
    shell=False,
    creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
)

def terminator():
    # 发送Ctrl+C对应的中断信号,替代强制终止
    proc.send_signal(signal.CTRL_C_EVENT)
    time.sleep(5)

terminator()

sub.py无需修改,这样子进程收到信号后会执行atexit钩子,生成foo.txt。

方案二:通过IPC让子进程主动退出(更可控)

通过标准输入管道给子进程发送退出指令,让子进程主动结束循环并执行清理逻辑:

## 修改后的mar.py
import os
import subprocess
import time

print('MASTER PID: ', os.getpid())
# 开启标准输入管道用于进程间通信
proc = subprocess.Popen(
    ["D:\\Miniconda3\\python.exe", r"C:\\Users\\J\\Desktop\\test\\sub.py"],
    shell=False,
    stdin=subprocess.PIPE
)

def terminator():
    # 发送退出指令
    proc.stdin.write(b'exit\n')
    proc.stdin.flush()
    proc.wait()  # 等待子进程完全退出
    time.sleep(1)

terminator()
## 修改后的sub.py
import atexit
import time
import os
import sys

print('SUB PID: ', os.getpid())
os.chdir("C:\\Users\\J\\Desktop\\test")

def handle_exit():
    with open("foo.txt", "w") as f:
        f.write("Life is too short, you need python")

atexit.register(handle_exit)

while True:
    print('alive')
    time.sleep(1)
    # 检查是否收到退出指令
    if sys.stdin.readline().strip() == 'exit':
        break

这种方式更灵活,你可以在子进程退出前添加更多自定义的清理逻辑,完全由子进程掌控退出流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:52:44