簡體   English   中英

如何使用python 2.7.6進行subprocess.call超時?

[英]How to make a subprocess.call timeout using python 2.7.6?

可能有人問過,但是在使用python 2.7時我找不到任何關於subprocess.call超時的信息

我總是使用2.7進行超時的一種簡單方法是使用subprocess.poll()time.sleep()以及延遲。 這是一個非常基本的例子:

import subprocess
import time

x = #some amount of seconds
delay = 1.0
timeout = int(x / delay)

args = #a string or array of arguments
task = subprocess.Popen(args)

#while the process is still executing and we haven't timed-out yet
while task.poll() is None and timeout > 0:
     #do other things too if necessary e.g. print, check resources, etc.
     time.sleep(delay)
     timeout -= delay

如果設置x = 600 ,則超時將達到10分鍾。 task.poll()將查詢進程是否已終止。 在這種情況下, time.sleep(delay)將休眠1秒,然后將超時減少1秒。 你可以根據自己的內容來玩這個部分,但基本概念始終如一。

希望這可以幫助!

subprocess.poll() https://docs.python.org/2/library/subprocess.html#popen-objects

你可以安裝subprocess32模塊 由@gps提到的的反向移植- subprocess在Python 3.2 / 3.3模塊上使用2.x的 它適用於Python 2.7,它包括Python 3.3的超時支持。

subprocess.call()只是Popen().wait() ,因此在timeout秒內中斷一個長時間運行的進程:

#!/usr/bin/env python
import time
from subprocess import Popen

p = Popen(*call_args)
time.sleep(timeout)
try:
    p.kill()
except OSError:
    pass # ignore
p.wait()

如果子進程可能會更快結束,那么便攜式解決方案是使用@ sussudio的答案中建議的Timer()

#!/usr/bin/env python
from subprocess import Popen
from threading import Timer

def kill(p):
    try:
        p.kill()
    except OSError:
        pass # ignore

p = Popen(*call_args)
t = Timer(timeout, kill, [p])
t.start()
p.wait()
t.cancel()

在Unix上,您可以按照@Alex Martelli的回答中的建議使用SIGALRM

#!/usr/bin/env python
import signal
from subprocess import Popen

class Alarm(Exception):
    pass

def alarm_handler(signum, frame):
    raise Alarm

signal.signal(signal.SIGALRM, alarm_handler)


p = Popen(*call_args)
signal.alarm(timeout)  # raise Alarm in 5 minutes
try:
    p.wait()
    signal.alarm(0)  # reset the alarm
except Alarm:
    p.kill()
    p.wait()

為了避免在這里使用線程和信號,Python 3上的subprocess模塊使用一個繁忙的循環,在Unix上使用waitpid(WNOHANG)調用, 在Windows 上使用 winapi.WaitForSingleObject()

您可以嘗試使用“easyprocess”

https://github.com/ponty/EasyProcess

它有許多你需要的功能,如“超時”

您可以使用subprocess32 通過@gps提到的 ,這是在Python 3.2的子標准庫模塊的反向移植- 3.5上使用的Python 2。

首先,安裝subprocess32模塊:

pip install subprocess32

這是一段代碼片段:

>>> import subprocess32
>>> print subprocess32.check_output(["python", "--version"])
Python 2.7.12

>>> subprocess32.check_output(["sleep", "infinity"], timeout=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/subprocess32.py", line 340, in check_output
    raise TimeoutExpired(process.args, timeout, output=output)
subprocess32.TimeoutExpired: Command '['sleep', 'infinity']' timed out after 3 seconds

注意,默認timeout=None ,這意味着永不超時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM