如何使用Python2.7.6设置subprocess.call超时?

2024-03-29 01:59:05 发布

您现在位置:Python中文网/ 问答频道 /正文


Tags: python
3条回答

您可以尝试使用“easyprocess”:

https://github.com/ponty/EasyProcess

它有许多您需要的功能,如“超时”。

您可以安装来自Python 3.2/3.3的subprocess模块的后台端口^{} modulementioned by @gps,以便在2.x上使用。它在Python 2.7上工作,并且包括来自python3.3的超时支持。

^{} is just ^{}因此要在timeout秒内中断长时间运行的进程:

#!/usr/bin/env python
import time
from subprocess import Popen

p = Popen(*call_args)
time.sleep(timeout)
try:
    p.kill()
except OSError:
    pass # ignore
p.wait()

如果子进程可能提前结束,则可移植的解决方案是use ^{} as suggested in @sussudio's answer

#!/usr/bin/env python
from subprocess import Popen
from threading import Timer

def kill(p):
    try:
        p.kill()
    except OSError:
        pass # ignore

p = Popen(*call_args)
t = Timer(timeout, kill, [p])
t.start()
p.wait()
t.cancel()

在Unix上,您可以use ^{} as suggested in @Alex Martelli's answer

#!/usr/bin/env python
import signal
from subprocess import Popen

class Alarm(Exception):
    pass

def alarm_handler(signum, frame):
    raise Alarm

signal.signal(signal.SIGALRM, alarm_handler)


p = Popen(*call_args)
signal.alarm(timeout)  # raise Alarm in 5 minutes
try:
    p.wait()
    signal.alarm(0)  # reset the alarm
except Alarm:
    p.kill()
    p.wait()

为了避免在这里使用线程和信号,Python 3上的subprocess模块使用了busy loop with ^{} calls on Unix^{} on Windows

我一直用2.7来做超时的一个简单方法是利用subprocess.poll()time.sleep()一起延迟。下面是一个非常基本的例子:

import subprocess
import time

x = #some amount of seconds
delay = 1.0
timeout = int(x / delay)

args = #a string or array of arguments
task = subprocess.Popen(args)

#while the process is still executing and we haven't timed-out yet
while task.poll() is None and timeout > 0:
     #do other things too if necessary e.g. print, check resources, etc.
     time.sleep(delay)
     timeout -= delay

如果设置了x = 600,则超时时间将为10分钟。而task.poll()将查询进程是否已终止。time.sleep(delay)在这种情况下将睡眠1秒,然后将超时时间减少1秒。你可以随心所欲地玩这个角色,但基本概念始终是一样的。

希望这有帮助!

subprocess.poll()https://docs.python.org/2/library/subprocess.html#popen-objects

相关问题 更多 >