我有 3 个文件:
sleeper.py
import subprocess
print('start sleeper')
subprocess.run(['sleep', '10'])
print('end sleeper')
waker.py
import subprocess
print('The waker begins')
try:
subprocess.run(['python3', 'sleeper.py'], timeout=5)
except subprocess.TimeoutExpired:
pass
print('The waker ends')
awake.py
import subprocess
print('Awake begin')
try:
subprocess.run(['python3', 'waker.py'], timeout=2.5)
except subprocess.TimeoutExpired:
pass
print('Awake end')
然后我运行python3 awake.py
。
但得到以下输出:
Awake begin
The waker begins
start sleeper
Awake end
end sleeper
实际上,更准确地说,我立即打印出前 3 行打印机,然后 2.5 秒后打印出第 4 行,然后我得到 bash 提示符,然后 7.5 秒后 end sleeper
出现在我的 bash 提示符上.
如何才能通过超时杀死子进程同时杀死该子进程运行的子进程?
最佳答案
run
应在超时到期时终止子进程。它也会终止 child 吗?你的情况似乎并非如此。解决方法是使用 Popen、轮询超时并终止进程和子进程。
似乎你不能同时拥有这两种方法:使用 run
并确保所有子进程都终止(当你收到 TimeoutException
时,该进程已经被终止,所以你输了 child 的踪迹)
proc = subprocess.Popen(args, stderr=errFile, stdout=outFile, universal_newlines=False)
wait_remaining_sec = 2.5
while proc.poll() is None and wait_remaining_sec > 0:
time.sleep(0.5)
wait_remaining_sec -= 0.5
if proc.poll() is None:
# process is still there: terminate it and subprocesses:
import psutil
parent_pid = proc.pid # we get the process pid
parent = psutil.Process(parent_pid)
for child in parent.children(recursive=True):
child.kill()
parent.kill()
轮询循环比单纯的 time.sleep(2.5)
调用更好,因为如果进程在超时之前结束,您不想等待 2.5 秒。如果进程之前结束,这不会导致超过 0.5 秒的延迟。
引用文献:
关于python - 嵌套子进程不停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52975079/