Python 如何一次性终止某个子进程下面的所有子进程?

2020-12-29 18:29:43 +08:00
 zictos
比如主进程 m 创建了子进程 p
子进程 p 又创建了子进程 p1 、p2 、p3 、p4,甚至 p1 下面又有创建别的子进程。

在主进程 m 处用 p.kill()或者 p.terminate()可以终止子进程 p,但是 p 创建的子进程 p1,p2,p3,p4 还会继续保持运行。

希望一次性把子进程 p 以及子进程 p 下面的子进程全部结束,并且主进程 m 继续保持运行。有办法吗?


ps:■■■■■■■■■■■■■■■■■■
官方帮助中有说到关于 terminate()的注意事项:进程的后代进程将不会被终止 —— 它们将简单地变成孤立的。

这样的话感觉 kill()或 terminate()有点坑,比如你的某个子进程使用到了某个第三方模块,该模块里面也用到了多进程,而你如果直接 kill 掉该子进程,但子进程下面创建的子进程却并不能 kill 掉,而且可能不容易察觉到,毕竟第三方模块不是自己写的。
4090 次点击
所在节点    Python
27 条回复
zictos
2020-12-30 18:44:46 +08:00
写成函数,只要传入某个进程的 pid 就可以杀死该进程以及该进程下面的子进程。把 killprocess(pid)中的 pid 替换为要杀的进程的 pid 即可

def killprocess(pid):
****import psutil
****childlist = psutil.Process(pid).children(recursive=True)
****for i in childlist:
********i.kill()
****psutil.Process(pid).kill()
abersheeran
2020-12-30 20:01:45 +08:00
@zictos 学到了。 原来还可以这么获取全部下属进程。
julyclyde
2020-12-31 16:28:34 +08:00
@zictos 你这个似乎只能 kill 一层?
正确的做法应该是深度优先遍历然后再从最深层往上 kill 吧
zictos
2020-12-31 16:35:16 +08:00
@julyclyde #23
针对 21 楼的代码,childlist 就已经包含了所有子进程对象了,直接用 for 遍历再逐个 kill 自然就是把所有子进程都杀死了。
最后一行 psutil.Process(pid).kill()是杀死 pid 为传入的 pid 的进程,前面的 for 是杀死 pid 下面的子进程、孙进程……
julyclyde
2020-12-31 16:48:16 +08:00
@zictos 哦。看到 recursive 了。不过顺序正确吗?
zictos
2020-12-31 17:04:08 +08:00
@julyclyde #25 我没研究过顺序,你可以自己测试下。反正我问题中的需求就是希望能获取某个进程下所有的子进程以及孙进程等等等等,然后杀死他们。所以顺序根本就不重要。
codehz
2021-01-11 22:22:16 +08:00
@zictos #24 考虑竞争条件,你杀进程的时候它也可以同时 fork 出一个新的(不一定是对抗,可能只是巧合,比如多进程编译的时候就不能这样做)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/740071

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX