我想在多线程python程序的每个线程中执行一个外部程序。
假设最大运行时间设置为1秒。如果启动过程在1秒内完成,则主程序捕获其输出以进行进一步处理。如果它在1秒内没有完成,主程序就会终止它并开始另一个新进程。
如何实现这个?
答案 0 :(得分:6)
您可以定期轮询:
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
然后你可以把上面的内容放在一个函数中并以线程的形式启动它。
答案 1 :(得分:3)
这是我使用的辅助函数:
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)
答案 2 :(得分:1)
Linux上讨厌的黑客攻击是使用timeout
程序来运行命令。但是,您可以选择更好的Python解决方案。
答案 3 :(得分:1)
这是一个使用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