Python部落组织翻译,禁止转载,欢迎转发
有一天我碰到一个需求,我需要和子进程交互,并且需要让它在一定时间内超时。不幸的,Python2没有让communicate方法超时的办法,所以communicate会一直运行到返回或者子进程自己关闭它。我在StackOverflow上找到很多中办法来解决这个问题,但是我想我最喜欢的办法是使用Python的Threading模块的Timer类:
import subprocess
from threading import Timer
kill = lambda process: process.kill
cmd = ["ping", "www.google.com"]
ping = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
my_timer = Timer(5, kill, [ping])
try:
my_timer.start
stdout, stderr = ping.communicate
finally:
my_timer.cancel
这个例子和我的实际需求并不完全一致,但是已经很像了。首先,这里我们有一个会一直运行下去的进程,并且我们需要和这个进程交互。在Linux上,如果你调用ping,那么它就会一直运行下去。这就是一个很好的例子。这里我写了一个lambda函数killing,这个函数会调用进程的kill方法。当我启动ping命令,并把它放在计时器里,这个计时器五秒超时,然后启动定时器。当这个进程运行时,我们搜集进程的标准输出和错误输出,直到进程死掉。最后,我们停止计时器清场。
Python3.5增加了一个能够接受一个timeout参数的run函数。根据文档,这个timeout参数会被传递给子进程的communicate方法,并且进程超时时会抛出一个TimeoutExpired异常。让我们来试一试:
>>> import subprocess
>>> cmd = ["ping", "www.google.com"]
>>> subprocess.run(cmd, timeout=5)
PING www.google.com (216.58.216.196) 56(84) bytes of data.
64 bytes from ord31s21-in-f4.1e100.net (216.58.216.196): icmp_seq=1 ttl=55 time=16.3 ms
64 bytes from ord31s21-in-f4.1e100.net (216.58.216.196): icmp_seq=2 ttl=55 time=19.4 ms
64 bytes from ord31s21-in-f4.1e100.net (216.58.216.196): icmp_seq=3 ttl=55 time=20.0 ms
64 bytes from ord31s21-in-f4.1e100.net (216.58.216.196): icmp_seq=4 ttl=55 time=19.4 ms
64 bytes from ord31s21-in-f4.1e100.net (216.58.216.196): icmp_seq=5 ttl=55 time=17.0 ms
Traceback (most recent call last):
Python Shell, prompt 3, line 1
File "/usr/local/lib/python3.5/subprocess.py", line 711, in run
stderr=stderr)
subprocess.TimeoutExpired: Command "["ping", "www.google.com"]" timed out after 5 seconds
显然确实就像文档中所说。这真的很有用,通常我们需要捕获这个异常
>>> try:
... subprocess.run(cmd, timeout=5)
... except subprocess.TimeoutExpired:
... print("process ran too long")
...
PING www.google.com (216.58.216.196) 56(84) bytes of data.
64 bytes from ord31s21-in-f196.1e100.net (216.58.216.196): icmp_seq=1 ttl=55 time=18.3 ms
64 bytes from ord31s21-in-f196.1e100.net (216.58.216.196): icmp_seq=2 ttl=55 time=21.1 ms
64 bytes from ord31s21-in-f196.1e100.net (216.58.216.196): icmp_seq=3 ttl=55 time=22.7 ms
64 bytes from ord31s21-in-f196.1e100.net (216.58.216.196): icmp_seq=4 ttl=55 time=20.3 ms
64 bytes from ord31s21-in-f196.1e100.net (216.58.216.196): icmp_seq=5 ttl=55 time=16.8 ms
process ran too long
现在我们捕获到了这个异常,我们可以做些其他的事情,比如保存异常信息。有趣的是,事实上,在Python3.3 subprocess就有了timeout参数。你可以在subprocess.call, check_output, 和 check_call中使用timeout参数,在Popen.wait中也有timeout参数。
了解野狗,请点击阅读原文。
声明:我要去上班所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,版权归原作者所有,原文出处。若您的权利被侵害,请联系删除。
本文标题:(怎么让python停止运行)(python怎样继续运行)
本文链接:https://www.51qsb.cn/article/6184.html