在Python中使用subprocess终止子进程的子进程
Python有没有办法找到通过subprocess创建的子进程的子进程,这样我就可以正确地结束它们?如果没有,确保子进程的子进程被结束的好方法是什么?
2 个回答
5
以下内容仅适用于Unix系统:
在子进程中调用 os.setsid() 会让这个子进程成为一个新会话的会话领导者,同时也是一个新 进程组 的领导者。如果你向这个进程组发送一个SIGTERM信号,它会把这个信号发送给所有由这个子进程启动的子进程。
你可以通过 subprocess.Popen(..., preexec_fn=os.setsid)
来实现这个功能。例如:
import signal
import os
import subprocess
import time
PIPE = subprocess.PIPE
proc = subprocess.Popen('ls -laR /', shell=True,
preexec_fn=os.setsid,
stdout=PIPE, stderr=PIPE)
time.sleep(2)
os.killpg(proc.pid, signal.SIGTERM)
运行这个代码不会有任何输出,但你可以用 ps ax
命令查看,发现子进程和它启动的 ls -laR
都已经被终止了。
但是如果你把
preexec_fn=os.setsid
注释掉,那么用 ps ax
查看时,你会看到类似下面的内容:
% ps ax | grep "ls -la"
5409 pts/3 S 0:00 /bin/sh -c ls -laR /
5410 pts/3 R 0:05 ls -laR /
所以如果没有 os.setsid
,ls -laR
和启动它的shell仍然在运行。记得要把它们杀掉:
% kill 5409
% kill 5410
1
这事儿不算简单,不过如果你的应用是在Linux系统上运行的,你可以通过查看/proc这个文件系统,来列出所有的进程ID(PID),这些进程的父进程ID(PPID)和你的小进程是一样的。