有什么参数或选项可以为Python的subprocess.Popen方法设置超时吗?
如下所示:
subprocess.Popen(['..'], ..., timeout=20)
?
发布于 2012-11-13 22:29:23
我建议看看threading
模块中的Timer
class。我用它来实现Popen
的超时。
首先,创建一个回调:
def timeout( p ):
if p.poll() is None:
print 'Error: process taking too long to complete--terminating'
p.kill()
然后打开流程:
proc = Popen( ... )
然后创建一个定时器,该定时器将调用回调,并将流程传递给它。
t = threading.Timer( 10.0, timeout, [proc] )
t.start()
t.join()
在程序后面的某个地方,您可能需要添加以下代码行:
t.cancel()
否则,python程序将一直运行,直到计时器结束运行。
编辑:我被告知存在竞争条件,subprocess
p
可能会在p.poll()
和p.kill()
调用之间终止。我相信下面的代码可以解决这个问题:
import errno
def timeout( p ):
if p.poll() is None:
try:
p.kill()
print 'Error: process taking too long to complete--terminating'
except OSError as e:
if e.errno != errno.ESRCH:
raise
但是,您可能希望清除异常处理,以便仅处理当子进程已正常终止时发生的特定异常。
发布于 2010-09-17 15:17:12
subprocess.Popen不会阻塞,所以你可以这样做:
import time
p = subprocess.Popen(['...'])
time.sleep(20)
if p.poll() is None:
p.kill()
print 'timed out'
else:
print p.communicate()
它有一个缺点,那就是您必须始终等待至少20秒才能完成。
发布于 2014-07-14 04:19:29
import subprocess, threading
class Command(object):
def __init__(self, cmd):
self.cmd = cmd
self.process = None
def run(self, timeout):
def target():
print 'Thread started'
self.process = subprocess.Popen(self.cmd, shell=True)
self.process.communicate()
print 'Thread finished'
thread = threading.Thread(target=target)
thread.start()
thread.join(timeout)
if thread.is_alive():
print 'Terminating process'
self.process.terminate()
thread.join()
print self.process.returncode
command = Command("echo 'Process started'; sleep 2; echo 'Process finished'")
command.run(timeout=3)
command.run(timeout=1)
此命令的输出应为:
Thread started
Process started
Process finished
Thread finished
0
Thread started
Process started
Terminating process
Thread finished
-15
其中可以看到,在第一次执行中,进程正确完成(返回代码0),而在第二次执行中,进程被终止(返回代码-15)。
我还没有在windows中测试过,但是,除了更新示例命令之外,我认为它应该可以工作,因为我在文档中没有发现任何说明thread.join或process.terminate不受支持的内容。
https://stackoverflow.com/questions/3733270
复制相似问题