从python中杀死一个子进程,包括它的子进程[重复]
Posted
技术标签:
【中文标题】从python中杀死一个子进程,包括它的子进程[重复]【英文标题】:Killing a subprocess including its children from python [duplicate] 【发布时间】:2011-02-07 23:54:04 【问题描述】:我正在使用 python 2.5 上的 subprocess 模块来生成一个 java 程序(准确地说是 selenium 服务器),如下所示:
import os
import subprocess
display = 0
log_file_path = "/tmp/selenium_log.txt"
selenium_port = 4455
selenium_folder_path = "/wherever/selenium/lies"
env = os.environ
env["DISPLAY"] = ":%d.0" % display
command = ["java",
"-server",
"-jar",
'selenium-server.jar',
"-port %d" % selenium_port]
log = open(log_file_path, 'a')
comm = ' '.join(command)
selenium_server_process = subprocess.Popen(comm,
cwd=selenium_folder_path,
stdout=log,
stderr=log,
env=env,
shell=True)
一旦自动化测试完成,这个进程应该被终止。我正在使用os.kill
来执行此操作:
os.killpg(selenium_server_process.pid, signal.SIGTERM)
selenium_server_process.wait()
这不起作用。原因是 shell 子进程为 java 生成了另一个进程,而我的 python 代码不知道该进程的 pid。我尝试使用os.killpg
杀死进程组,但这也杀死了首先运行此代码的python 进程。由于其他原因,将 shell 设置为 false,从而避免 java 在 shell 环境中运行,也是不可能的。
如何杀死 shell 和它生成的任何其他进程?
【问题讨论】:
相关:How to terminate a python subprocess launched with shell=True 如果我只想杀死子进程怎么办? 【参考方案1】:处理一般问题:
p=subprocess.Popen(your_command, preexec_fn=os.setsid)
os.killpg(os.getpgid(p.pid), signal.SIGTERM)
setsid
将在新会话中运行程序,从而为它及其子进程分配一个新进程组。因此调用os.killpg
也不会关闭你自己的python 进程。
【讨论】:
不用setsid
;你可以call os.setsid
in Python
不,你不能......这将改变进程本身的会话,如果你所追求的只是杀死孩子,那不是你想要的
重读问题的标题:"Killing a subprocess including its children from python"
fyi,preexec_fn 在 fork 之后执行(在子进程中)
标题说“子进程”+子进程,我说“子进程”(意思是子进程+子进程),你说“调用进程本身+子进程(子进程及其子进程)”【参考方案2】:
在这种情况下,显而易见的解决方案是不涉及外壳:
import os
import subprocess
display = 0
log_file_path = "/tmp/selenium_log.txt"
selenium_port = 4455
selenium_folder_path = "/wherever/selenium/lies"
env = os.environ
env["DISPLAY"] = ":%d.0" % display
command = ["java",
"-server",
"-jar",
'selenium-server.jar',
"-port",
str(selenium_port)]
log = open(log_file_path, 'a')
selenium_server_process = subprocess.Popen(command,
cwd=selenium_folder_path,
stdout=log,
stderr=subprocess.STDOUT,
env=env)
这将使进程直接成为Java进程。请记住,它可能仍会生成不属于进程组的进程,因此 os.killpg 可能仍然不知道要杀死它们。
如果你有理由调用 shell(上面的代码没有,没有 shell 你不能做一些事情,但假设你这样做了),你必须让 shell 传递你的 pid过程它以某种方式开始。这样做并不简单,而是视情况而定。
【讨论】:
或者,如果您出于任何原因确实涉及 shell(假设您想要扩展/替换/其他),请在开头使用“exec”以避免 shell 分叉。 (具体来说,只需在“command”定义的开头添加“exec”就可以解决您的问题。) @moshez,太棒了!做到了。非常感谢。 你真的有 原因 让 shell 参与进来吗?很少有。以上是关于从python中杀死一个子进程,包括它的子进程[重复]的主要内容,如果未能解决你的问题,请参考以下文章