了解 subprocess.TimeoutExpired,想在超时发生后终止 child 进程
Understanding subprocess.TimeoutExpired, want to kill a child process after a timeout occurs
有人可以帮助我了解超时参数在子流程模块中的工作原理,以及如何正确使用 subprocess.TimeoutExpired 异常吗?
我的用例是我有一个主 运行ner 程序,它 运行 是一个 child 进程,作为其重复例程的一部分。 child 进程有时会挂起。我想防止这个挂起阻碍一切。
我在想我可以使用超时参数给 child 这么长的时间给 运行。但是,在我下面的示例程序中,行为并不是我所期望的。当 parent.py 为 运行 时,它会启动 child.py 并且我可以看到 child.py 的输出正在计数。 4 秒后 parent.py 确实得到 subprocess.TimeoutExpired 异常,但是 child.py 的输出不断出现。这让我相信 child.py 进程实际上并没有被杀死。文档似乎暗示它将被杀死:
The timeout argument is passed to Popen.wait(). If the timeout expires, the child process will be killed and then waited for again. The TimeoutExpired exception will be re-raised after the child process has terminated.
那么我该如何解决这个问题呢?当我收到超时异常时,我是否需要以某种方式自行终止我的 child 进程?
感谢您的帮助。
parent.py
#!/usr/bin/env python3
import os
import sys
import subprocess
p = subprocess.Popen("/path/to/python3 /path/to/child.py", shell=True)
try:
p.wait(timeout=4)
except subprocess.TimeoutExpired:
print("we got a timeout. exiting")
sys.exit(1)
child.py
#!/usr/bin/env python3
import os
import sys
import time
for i in range(200):
print("i is {}".format(i))
time.sleep(1)
看来您确实需要添加一个调用:
p.terminate()
在你的父进程中的sys.exit
之前根据当前documentation你引用的位只适用于subprocess.call
,那就是不 你在这里用的是什么
摘自文档:
If the process does not terminate after timeout seconds, raise a TimeoutExpired exception. It is safe to catch this exception and retry the wait.
意味着您可以捕获异常,除非您终止进程(或 python),否则进程将继续执行。在你的情况下,因为你正在做
sys.exit(1)
然后 python 本身将被终止,Popen 对象将被垃圾收集。
有人可以帮助我了解超时参数在子流程模块中的工作原理,以及如何正确使用 subprocess.TimeoutExpired 异常吗?
我的用例是我有一个主 运行ner 程序,它 运行 是一个 child 进程,作为其重复例程的一部分。 child 进程有时会挂起。我想防止这个挂起阻碍一切。
我在想我可以使用超时参数给 child 这么长的时间给 运行。但是,在我下面的示例程序中,行为并不是我所期望的。当 parent.py 为 运行 时,它会启动 child.py 并且我可以看到 child.py 的输出正在计数。 4 秒后 parent.py 确实得到 subprocess.TimeoutExpired 异常,但是 child.py 的输出不断出现。这让我相信 child.py 进程实际上并没有被杀死。文档似乎暗示它将被杀死:
The timeout argument is passed to Popen.wait(). If the timeout expires, the child process will be killed and then waited for again. The TimeoutExpired exception will be re-raised after the child process has terminated.
那么我该如何解决这个问题呢?当我收到超时异常时,我是否需要以某种方式自行终止我的 child 进程?
感谢您的帮助。
parent.py
#!/usr/bin/env python3
import os
import sys
import subprocess
p = subprocess.Popen("/path/to/python3 /path/to/child.py", shell=True)
try:
p.wait(timeout=4)
except subprocess.TimeoutExpired:
print("we got a timeout. exiting")
sys.exit(1)
child.py
#!/usr/bin/env python3
import os
import sys
import time
for i in range(200):
print("i is {}".format(i))
time.sleep(1)
看来您确实需要添加一个调用:
p.terminate()
在你的父进程中的sys.exit
之前根据当前documentation你引用的位只适用于subprocess.call
,那就是不 你在这里用的是什么
摘自文档:
If the process does not terminate after timeout seconds, raise a TimeoutExpired exception. It is safe to catch this exception and retry the wait.
意味着您可以捕获异常,除非您终止进程(或 python),否则进程将继续执行。在你的情况下,因为你正在做
sys.exit(1)
然后 python 本身将被终止,Popen 对象将被垃圾收集。