我想在多線程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