0

0

subprocess 如何在 timeout 时优雅杀死子进程树

冰川箭仙

冰川箭仙

发布时间:2026-01-27 18:18:09

|

548人浏览过

|

来源于php中文网

原创

subprocess.run() 的 timeout 参数只终止主进程,不清理子进程树;应使用 start_new_session=True(Linux/macOS)或 CREATE_NEW_PROCESS_GROUP(Windows)配合 killpg/CTRL_BREAK_EVENT,或用 psutil 显式遍历终止整个进程树。

subprocess 如何在 timeout 时优雅杀死子进程树

subprocess.run() 的 timeout 参数只杀主进程,不清理子进程树

Python 的 subprocess.run()subprocess.Popen.wait(timeout=...) 在超时时只会向直接子进程发送信号(如 SIGTERM),但不会递归终止其派生的整个进程树。这意味着 shell 启动的命令链(如 bash -c "sleep 10 & sleep 20")或通过 nohup/& 后台启动的子进程大概率残留。

用 start_new_session=True 配合 os.killpg() 杀整个进程组

关键在于让子进程及其后代运行在独立会话(session)中,这样就能用进程组 ID(PGID)一次性终结整棵树。核心是:start_new_session=True(Linux/macOS)或 creationflags=subprocess.CREATE_NEW_PROCESS_GROUP(Windows)。

  • Linux/macOS 下:调用 os.setsid() 创建新会话,主进程成为会话首进程,其 PGID = PID;后续 fork 出的子进程默认加入该 PGID
  • 启动时必须加 start_new_session=True,否则 os.getpgid(proc.pid) 可能报错或返回父进程组 ID
  • 超时后用 os.killpg(os.getpgid(proc.pid), signal.SIGTERM) 终止整个组,再 wait() 收尸
import subprocess, os, signal, time

proc = subprocess.Popen( ["bash", "-c", "sleep 5; echo 'done'"], start_newsession=True, # 必须! stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) try: stdout, = proc.communicate(timeout=2) except subprocess.TimeoutExpired: os.killpg(os.getpgid(proc.pid), signal.SIGTERM) proc.wait() # 等待进程组彻底退出

Windows 上要用 CREATE_NEW_PROCESS_GROUP + CTRL_BREAK_EVENT

Windows 没有 POSIX 进程组概念,os.killpg 不可用。必须用 subprocess.CREATE_NEW_PROCESS_GROUP 创建独立进程组,再用 os.kill() 发送 signal.CTRL_BREAK_EVENT(不能用 CTRL_C_EVENT,它可能被目标进程忽略)。

唱鸭
唱鸭

音乐创作全流程的AI自动作曲工具,集 AI 辅助作词、AI 自动作曲、编曲、混音于一体

下载
  • CTRL_BREAK_EVENT 能传递给整个控制台进程组,比 TerminateProcess 更温和
  • 必须确保子进程是控制台应用(非 GUI),否则信号无效
  • 调用前需先 proc.terminate() 或直接 os.kill(proc.pid, signal.CTRL_BREAK_EVENT),之后仍要 proc.wait()

更健壮的做法:用 psutil 回收所有后代进程

如果无法控制启动参数(比如不能加 start_new_session),或者跨平台兼容性要求高,推荐用 psutil 手动遍历并终止子树。它不依赖会话机制,而是靠 proc.children(recursive=True) 获取全部后代。

  • 安装:pip install psutil
  • 注意:Windows 上需管理员权限才能终止某些系统相关子进程
  • 务必按逆序终止(先叶子后父进程),避免子进程被 init 进程领养而逃逸
  • 示例中 proc.children(recursive=True) 返回的是实时快照,若进程瞬间启停,可能漏掉极短命子进程
import subprocess, psutil, time

proc = subprocess.Popen(["bash", "-c", "sleep 3 &"]) try: proc.communicate(timeout=1) except subprocess.TimeoutExpired: parent = psutil.Process(proc.pid) children = parent.children(recursive=True) for child in reversed(children): # 先杀孙子,再杀儿子 try: child.terminate() except (psutil.NoSuchProcess, psutil.AccessDenied): pass try: parent.terminate() parent.wait(timeout=3) except (psutil.NoSuchProcess, psutil.TimeoutExpired): pass

实际项目里,start_new_session=True 是最轻量且可靠的选择,但前提是能掌控子进程启动方式;一旦涉及遗留脚本、第三方二进制或容器化环境,psutil 的显式树遍历反而更可控——毕竟进程关系不是靠约定,而是靠实时探测。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pip安装使用方法
pip安装使用方法

安装步骤:1、确保Python已经正确安装在您的计算机上;2、下载“get-pip.py”脚本;3、按下Win + R键,然后输入cmd并按下Enter键来打开命令行窗口;4、在命令行窗口中,使用cd命令切换到“get-pip.py”所在的目录;5、执行安装命令;6、验证安装结果即可。大家可以访问本专题下的文章,了解pip安装使用方法的更多内容。

339

2023.10.09

更新pip版本
更新pip版本

更新pip版本方法有使用pip自身更新、使用操作系统自带的包管理工具、使用python包管理工具、手动安装最新版本。想了解更多相关的内容,请阅读专题下面的文章。

412

2024.12.20

pip设置清华源
pip设置清华源

设置方法:1、打开终端或命令提示符窗口;2、运行“touch ~/.pip/pip.conf”命令创建一个名为pip的配置文件;3、打开pip.conf文件,然后添加“[global];index-url = https://pypi.tuna.tsinghua.edu.cn/simple”内容,这将把pip的镜像源设置为清华大学的镜像源;4、保存并关闭文件即可。

761

2024.12.23

python升级pip
python升级pip

本专题整合了python升级pip相关教程,阅读下面的文章了解更多详细内容。

349

2025.07.23

session失效的原因
session失效的原因

session失效的原因有会话超时、会话数量限制、会话完整性检查、服务器重启、浏览器或设备问题等等。详细介绍:1、会话超时:服务器为Session设置了一个默认的超时时间,当用户在一段时间内没有与服务器交互时,Session将自动失效;2、会话数量限制:服务器为每个用户的Session数量设置了一个限制,当用户创建的Session数量超过这个限制时,最新的会覆盖最早的等等。

315

2023.10.17

session失效解决方法
session失效解决方法

session失效通常是由于 session 的生存时间过期或者服务器关闭导致的。其解决办法:1、延长session的生存时间;2、使用持久化存储;3、使用cookie;4、异步更新session;5、使用会话管理中间件。

748

2023.10.18

cookie与session的区别
cookie与session的区别

本专题整合了cookie与session的区别和使用方法等相关内容,阅读专题下面的文章了解更详细的内容。

91

2025.08.19

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

737

2023.07.26

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

10

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.9万人学习

Git 教程
Git 教程

共21课时 | 3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号