Python运行Subprocess一段时间

时间:2016-02-28 16:54:23

标签: python

我正在测试某个exe文件,我想为我的脚本实现一种方法来确定它已进入无限循环。 这是我目前的代码:

import subprocess
import os
import sys
runs = 1000 # Default run is 1000
if len(sys.argv)>1: # If I want to change the num of runs
    runs = int(sys.argv[1])
FNULL = open(os.devnull, 'w')
logfile = open('logfile', 'w')
args = "exe" # Exe to test
succ = 0
fail = 0
for i in range (0,runs):
    if subprocess.call(args,stdout = logfile, stderr = FNULL) == 100:
        succ += 1 # If returned 100 then success
    else:
        fail += 1 # Else Failed
        break # Break on failure
    open('logfile', 'w').close() # Empties the file
print "Succ: %d , Fail: %d" % (succ, fail)

让我说我定义了一个无限循环,因为我的exe运行时间超过5秒。 我将如何实现这一目标? 感谢您的帮助,包括有关当前代码的提示!

3 个答案:

答案 0 :(得分:2)

启动一个threading.Timer,它会在5秒后终止该过程并报告该契约已完成。您需要在不同的步骤中创建并等待该过程,因此请使用Popen对象而不是call。我创建了一个测试程序,它使用sleep来模拟你的无限列表。

import subprocess
import os
import sys
import threading

def on_timeout(proc, status_dict):
    """Kill process on timeout and note as status_dict['timeout']=True"""
    # a container used to pass status back to calling thread
    status_dict['timeout'] = True
    print("timed out")
    proc.kill()

runs = 1000 # Default run is 1000
if len(sys.argv)>1: # If I want to change the num of runs
    runs = int(sys.argv[1])
FNULL = open(os.devnull, 'w')
logfile = open('logfile', 'w')
# replacing example with a running program. This is a simple python
# we can call from the command line.
# args = "exe" # Exe to test
test_script = "import time;import sys;time.sleep(%d);sys.exit(100)"
succ = 0
fail = 0
for i in range (0,runs):
    # set by timer 
    status_dict = {'timeout':False}
    # test prog sleeps i seconds
    args = ["python", "-c", test_script % i]
    proc = subprocess.Popen(args, 
        stdout = logfile, stderr = FNULL)
    # trigger timout and kill process in 5 seconds
    timer = threading.Timer(5, on_timeout, (proc, status_dict))
    timer.start()
    proc.wait()
    # in case we didn't hit timeout
    timer.cancel()
    print status_dict
    if not status_dict['timeout'] and proc.returncode == 100:
        succ += 1 # If returned 100 then success
    else:
        fail += 1 # Else Failed
        break # Break on failure
    open('logfile', 'w').close() # Empties the file
print "Succ: %d , Fail: %d" % (succ, fail)

答案 1 :(得分:0)

这对我有用

import subprocess
import time

for _ in range(999999): # or whatever
    p1 = subprocess.Popen(['exe_file', 'arg1', 'arg2'])
    time.sleep(0.1)  # wait a small amount of time, hopefully the process ends fast
    return_code = p1.poll()

    if return_code is not None: # we're happy, the process ended fast
        ... # do something to celebrate
    else:  # we're sad. let the process run for at most 5 seconds
        time.sleep(5)   
        p1.terminate()    # this kills the process. try p1.kill() too...
        p1.wait()   #  this cleans up the process registry.

免责声明:这是linux代码。在Windows上可能会有所不同,但你可以先查看一下,然后在这里阅读一些关于子进程库的内容以及linux和windows之间的差异。

答案 2 :(得分:0)

在python3.3中,超时被添加到subprocess.call。如果您使用的是python3.3,那么您只需更改subprocess.call即可将超时作为参数:

   subprocess.call(args,stdout = logfile, stderr = FNULL, timeout=5)

如果你使用的是python2.7,你可以使用subprocess32包,或者你需要编写一些额外的代码来处理超时。

如果安装subprocess32模块,可以使用subprocess.call的上述方法,并将timeout作为参数。

否则,此代码可以帮助您实现相同的功能:

from subprocess import Popen
timeout=5 #5 seconds
p = Popen(args, shell = True, stdout = logfile, stderr = FNULL)
while (p.poll() is None and timeout > 0):
    time.sleep(1)
    timeout-=1

if timeout <= 0:
    p.terminate()  #Timeout