我想在多线程python程序的每个线程中执行一个外部程序。以指定的最大运行时间运行外部程序
假设最大运行时间设置为1秒。如果启动的过程在1秒内完成,主程序将捕获其输出以供进一步处理。如果它在1秒内没有完成,主程序只是终止它并开始另一个新进程。
如何实现这个?
我想在多线程python程序的每个线程中执行一个外部程序。以指定的最大运行时间运行外部程序
假设最大运行时间设置为1秒。如果启动的过程在1秒内完成,主程序将捕获其输出以供进一步处理。如果它在1秒内没有完成,主程序只是终止它并开始另一个新进程。
如何实现这个?
你可以定期轮询:
import subprocess, time
s = subprocess.Popen(['foo', 'args'])
timeout = 1
poll_period = 0.1
s.poll()
while s.returncode is None and timeout > 0:
time.sleep(poll_period)
timeout -= poll_period
s.poll()
if timeout <= 0:
s.kill() # timed out
else:
pass # completed
然后,您可以只把上面的功能,并启动它作为一个线程。
它不会捕获孩子的输出。 – jfs 2015-01-06 07:06:04
linux上令人讨厌的黑客攻击是使用timeout
程序来运行该命令。但是,您可以选择更好的所有Python解决方案。
这是辅助函数使用:
def run_with_timeout(command, timeout):
import time
import subprocess
p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while timeout > 0:
if p.poll() is not None:
return p.communicate()
time.sleep(0.1)
timeout -= 0.1
else:
try:
p.kill()
except OSError as e:
if e.errno != 3:
raise
return (None, None)
喜欢它:-)适合我们 - 非常感谢你! – 2013-04-15 21:05:25
1.如果'command'生成大输出(足以填充其OS stdout/stderr管道缓冲区),则不会返回任何输出。您应该在等待超时时读取输出。 2.(小细节)如果'timeout'很大,那么循环会漂移,因为'time.sleep(0.1)'可以少睡/超过'0.1'秒。你可以使用'while endtime> timer():'来代替。 – jfs 2015-01-06 07:05:25
这里是使用pexpect
模块(我需要捕捉程序的输出才跑进超时,我没能做到的解决方案这与subprocess.Popen
):
import pexpect
timeout = ... # timeout in seconds
proc = pexpect.spawn('foo', ['args'], timeout = timeout)
result = proc.expect([ pexpect.EOF, pexpect.TIMEOUT])
if result == 0:
# program terminated by itself
...
else:
# result is 1 here, we ran into the timeout
...
print "program's output:", print proc.before
相关:[子带超时](http://stackoverflow.com/q/1191374/4279) – jfs 2015-01-06 06:59:03
相关:[停止读在Python过程输出,而不挂?](HTTP: //stackoverflow.com/a/4418891/4279) – jfs 2015-01-06 06:59:48