2016-04-13 17 views
1

子超時=秒數不爲我工作,如果我按照Python文檔的建議:超時的子流程:TimeoutExpired異常後要做什麼?

# copy+pasteable snippet :-) 
import subprocess32 as subprocess 
import datetime 

now=datetime.datetime.now() 
pipe=subprocess.Popen('sleep 5', shell=True, stdout=subprocess.PIPE) 
try: 
    pipe.communicate(timeout=1) 
except subprocess.TimeoutExpired, exc: 
    time_delta=datetime.datetime.now()-now 
    print(time_delta) 
    assert time_delta<datetime.timedelta(seconds=3), time_delta 
    pipe.kill() 
    outs, errs = pipe.communicate() 
    time_delta=datetime.datetime.now()-now 
    print(time_delta) 
    assert time_delta<datetime.timedelta(seconds=3), time_delta 
    print('OK') 

該文檔建議TimeoutExpired後使用pipe.kill()和pipe.communicate():https://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate

它不適合我。第二個communicate()不會很快返回。

例外:

0:00:01.0
0:00:05.002919 
Traceback (most recent call last): 
    File "/home/foo/src/test_timeout.py", line 16, in <module> 
    assert time_delta<datetime.timedelta(seconds=3), time_delta 
AssertionError: 0:00:05.002919 

如果我使用['sleep', '5']代替shell=True,那麼它的工作原理。 如果我不提供stdout=subprocess.PIPE,那麼它也適用。

我猜shell.kill()沒有反應。

解決此問題的最佳方法是什麼?

回答

1

一般模式:catch TimeoutExpired,殺死啓動進程,再次調用.communicate()是正確的。

問題是代碼中的pipe.kill()只會殺死shell,而其後代進程(如/bin/sleep)可能會繼續運行。見How to terminate a python subprocess launched with shell=True

注意:如果需要;沒有必要等待孫子們的過程。請參閱Python subprocess .check_call vs .check_output

+0

感謝您指向其他StackO問題的鏈接。我把我的問題標記爲重複。 – guettli