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

Python父进程终止后无法终止已启动子进程的问题求助

Python父进程终止后无法终止已启动子进程的问题求助

我来帮你搞定这个问题!首先咱们得先弄明白为啥会出现这种情况:你现在的master脚本启动完三个子进程之后就直接退出了(或者你按Ctrl+C的时候,master已经把所有子进程都启动好了),这些子进程会变成孤儿进程,被系统的init(或者systemd)进程接管,所以会继续跑下去。而且你原来的try-except只包裹了启动子进程的代码,根本覆盖不到master启动完成后的中断信号处理。

下面给你两个实用的解决方案,你可以根据需求选:

方案一:保存子进程实例,主动终止

这个方法最直观,让master脚本保持运行,捕获中断信号后逐个终止所有子进程。修改后的master脚本如下:

import sys, subprocess, os, signal
from time import sleep

d = ['fool', 'gool', 'lool']
children = []  # 用来保存所有子进程实例

try:
    # 启动所有子进程并记录
    for i in range(3):
        proc = subprocess.Popen(
            ['python3', 'child.py', d[i], str(i + 3)],
            stdin=subprocess.PIPE
        )
        children.append(proc)
    
    # 让master保持运行状态,直到收到中断信号
    while True:
        sleep(1)
except KeyboardInterrupt:
    print("收到终止信号,正在关闭所有子进程...")
    # 遍历所有子进程,发送终止信号
    for proc in children:
        proc.terminate()  # 如果terminate不够用,可以换成proc.kill()强制杀死
    sys.exit(0)

这样当你按Ctrl+C时,master会捕获到KeyboardInterrupt,然后逐个通知子进程终止,完美解决问题。

方案二:使用进程组批量终止

如果子进程数量很多,逐个终止太麻烦,可以用进程组的方式,一次性把所有子进程都干掉。这个方法在Linux/macOS下效果很好,修改后的master脚本:

import sys, subprocess, os, signal
from time import sleep

d = ['fool', 'gool', 'lool']
children = []

# 定义信号处理函数,收到中断时终止整个进程组
def handle_interrupt(sig, frame):
    print("正在终止所有子进程...")
    # 向当前进程组发送终止信号
    os.killpg(os.getpgid(0), signal.SIGTERM)
    sys.exit(0)

# 注册SIGINT信号(也就是Ctrl+C触发的信号)的处理函数
signal.signal(signal.SIGINT, handle_interrupt)

try:
    for i in range(3):
        proc = subprocess.Popen(
            ['python3', 'child.py', d[i], str(i + 3)],
            stdin=subprocess.PIPE,
            preexec_fn=os.setsid  # 让子进程加入新的会话/进程组
        )
        children.append(proc)
    
    # 保持master运行
    while True:
        sleep(1)
except Exception as e:
    print(f"启动子进程时出错:{str(e)}")
    for proc in children:
        proc.terminate()
    sys.exit(1)

这里用preexec_fn=os.setsid让每个子进程都加入同一个进程组,当master收到Ctrl+C时,直接向整个进程组发送终止信号,所有子进程都会收到并停止运行。

另外提个小细节:你的child脚本里每次循环都用open(f"{arg}.txt", "w"),这会每次覆盖文件内容,如果你想追加内容的话,可以改成open(f"{arg}.txt", "a")哦~

备注:内容来源于stack exchange,提问作者NedStarkOfWinterfell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 09:34:36