繁体   English   中英

如何在python中彻底杀死子进程

[英]How to cleanly kill subprocesses in python

我们使用python进程来管理长时间运行的python子进程。 偶尔需要杀死子程序。 kill命令不会完全终止进程,只会使其失效。

运行以下脚本演示了此行为。

import subprocess
p = subprocess.Popen(['sleep', '400'], stdout=subprocess.PIPE, shell=False)

要么

p = subprocess.Popen('sleep 400', stdout=subprocess.PIPE, shell=True)

将创建一个子进程。

p.terminate() 
p.kill()

对这个过程没有任何作用。 ps aux | grep sleep演示 ps aux | grep sleep

$ ps aux| grep 'sleep'
User       8062  0.0  0.0   7292   764 pts/7    S    14:53   0:00 sleep 400

这个过程没有被杀死/被解散。 使用带有'kill'pid作为参数的subprocess.call()函数将发出kill命令。

subprocess.call(['kill', str(p.pid)])

这会杀死这个过程,但它现在已经不存在了。

$ ps aux | grep 'sleep'
User       8062  0.0  0.0      0     0 pts/7    Z+   14:51   0:00 [sleep] <defunct>

如果队列运行的时间足够长,它最终会达到最大进程数,还是最终会收到已解散的进程并且没问题呢?

如果答案是前者,我如何在不杀死父进程的情况下处理python中的defunct进程?

有没有更好的杀死进程的方法?

这里有两个主要问题:

第一个问题:如果你使用的是shell=True ,那么你就是要杀死运行进程的shell ,而不是进程本身。 在其父母被杀害的情况下,子进程将无法立即/不会被杀死。

在你的情况下,你正在使用不是内置的sleep ,所以你可以删除shell=True ,并且Popen会产生实际的进程id: p.terminate()可以工作。

您可以(并且您应该)在大多数情况下避免使用shell=True ,即使它需要额外的python编码工作(将2个命令组合在一起,重定向输入/输出,所有这些情况都可以通过一个或多个Popen很好地处理, 而不需要 shell=True

并且(第二期)如果在该修复之后终止该进程仍然不存在,则可以调用p.wait() (来自问题)。 似乎调用terminate是不够的。 Popen对象需要进行垃圾回收。

你应该在终止子进程后调用p.wait()来清除进程表。 这应该删除僵尸进程(处于defunct状态)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM