我想用subprocess.Popen
来运行一个进程,并满足以下要求。Preproious Popen管道
我要管
stdout
和stderr
回Popen
呼叫者的进程中运行。如果它仍在运行,我想在
timeout
秒后终止进程。
我来了subprocess
API中的一个缺陷意味着它不能满足在同一时间这两个要求的结论。请看下面的玩具节目:
chatty.py
while True:
print 'Hi'
silence.py
while True:
pass
caller.py
import subprocess
import time
def go(command, timeout=60):
proc = subprocess.Popen(command, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
start = time.time()
while proc.poll() is None:
print proc.stdout.read(1024) # <----- Line of interest
if time.time() - start >= timeout:
proc.kill()
break
else:
time.sleep(1)
考虑上面的标记线。
如果包含,
go('python silence.py')
将永远挂 - 不是短短60秒内 - 因为read
是一个阻塞调用,直到1024
字节或流的末尾,既不一直不停地走来。如果它被评论,
go('python chatty.py')
将一遍又一遍地打印出'Hi'
,但是它如何在生成时被回送?proc.communicate()
阻塞直到流结束。
我将很高兴与替换需求(1)以上的解决方案“的情况下并没有出现超时,我想stdout
和stderr
一旦算法结束。”即使这是有问题的。我的实施尝试如下。
speech.py
for i in xrange(0, 10000):
print 'Hi'
caller2.py
import subprocess
import time
def go2(command, timeout=60):
proc = subprocess.Popen(command, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
start = time.time()
while True:
if proc.poll() is not None:
print proc.communicate()
break
elif time.time() - start >= timeout:
proc.kill()
break
else:
time.sleep(1)
但即使这样仍然有问题。即使python speech.py
只需几秒钟,go2('python speech.py')
也需要60秒。这是因为print 'Hi'
在speech.py
中的呼叫阻塞,直到在进程被终止时调用proc.communicate()
。由于proc.stdout.read
出现了silence.py
之前出现的问题,因此我对如何使这项工作非常困难。
如何获得stdout
和stderr
以及超时行为?
看起来很有希望。明天试试看。 – 2014-11-05 01:45:53