函数调用超时,Python

时间:2015-07-28 01:08:09

标签: python function timeout

我有这段代码

    r = x.run("prog", ["-4"], ['\tab \t cd\n', ' \t ab cd \n', '\ta\b\b\b\tb\n'])

其中"prog"是可执行文件的名称,"-4""prog"使用的命令行参数,'\tab \t cd\n', ' \t ab cd \n', '\ta\b\b\b\tb\n'是文件{{1}的输入文本1}}

我的"prog"功能是......

run

我想在 def run(self, prog, args, input): global debug result = None prog = os.path.join(".",prog) command = [prog] + args self.createFile(CompileAndExecute.stdinName, input) cwd = os.getcwd() os.chdir(self.tmpdir) stream0 = open(CompileAndExecute.stdinName, "r") stream1 = open(CompileAndExecute.stdoutName, "w") stream2 = open(CompileAndExecute.stderrName, "w") p = None try: p = subprocess.call(command, stdin=stream0, stdout=stream1, stderr=stream2) except: result = sys.exc_info() if p != None: p.kill() finally: stream0.close() stream1.close() stream2.close() os.remove(CompileAndExecute.stdinName) os.chdir(cwd) return result 函数中添加另一个参数,名为run。 基本上,我想要它,以便如果我的timeout函数花费的时间超过5秒,我会调用run并在那里结束。

我的Sys.exit(1)函数的正确调用,添加了run参数,将是

timeout

我的完整代码的一般概念,所有这些都不在这里,是编译并执行一个C文件并检查它的输出是否应该是它。

我被推荐参见Python3库文档的第17.5.1节,以获取有关如何实现超时的信息,但是无法理解如何实现。我尝试了类似问题的一些解决方案,但它没有成功。

任何帮助?

编辑: 有关r = x.run("prog", ["-4"], ['\tab \t cd\n', ' \t ab cd \n', '\ta\b\b\b\tb\n'], 5)函数的更多信息..

run

prog参数是一个字符串,它指定临时目录中可执行文件的名称。 args参数包含一个字符串列表,这些字符串将用作prog编写的程序的命令行参数。 run方法执行程序,提供命令行参数。如果程序在运行时从其标准输入读取,那么该标准输入将从名为input的参数中获取。输入参数是一个字符串列表;每个字符串代表一行文本输入,由程序读取。 当run方法返回时,结果为None(表示成功完成)或字符串(指定程序未执行或未成功完成的原因)。无论函数调用返回什么,都应检查标准输出流和标准错误输出流。

run(self, prog,args=[],input=[])是在{..}找到CompileAndExecute的班级名称。

run

更新: 在一些帮助之后,我收到了语法错误

class CompileAndExecute:
"""The class provides methods for compiling and testing
a program in a temporary directory."""
stdoutName = ".stdout.txt"
stderrName = ".stderr.txt"
stdinName  = ".stdin.txt"

# constructor, creates temporary directory
def __init__(self, compiler):
    self.compiler = compiler
    self.tmpdir = tempfile.mkdtemp()

对于上述块中的代码行 def run(self, prog, args, input): global debug result = None prog = os.path.join(".",prog) command = [prog] + args self.createFile(CompileAndExecute.stdinName, input) cwd = os.getcwd() os.chdir(self.tmpdir) stream0 = open(CompileAndExecute.stdinName, "r") stream1 = open(CompileAndExecute.stdoutName, "w") stream2 = open(CompileAndExecute.stderrName, "w") p = None try: p = subprocess.call(command, stdin=stream0, stdout=stream1, stderr=stream2, timeout = 5) except subprocess.TimeoutExpired: sys.exit(1) except: result = sys.exc_info() if p != None: p.kill() finally: stream0.close() stream1.close() stream2.close() os.remove(CompileAndExecute.stdinName) os.chdir(cwd) return result

1 个答案:

答案 0 :(得分:1)

对于Python 3+,您可以使用subprocess.calltimeout参数,传入要指定的超时,然后如果超时在子进程终止之前到期,则子进程将终止子进程并引发您可以捕获的subprocess.TimeoutExpired异常,然后调用sys.exit(1)

所以在你的代码中,你会这样做 -

try:
    p = subprocess.call(command,
        stdin=stream0, stdout=stream1, stderr=stream2, timeout=5)
except subprocess.TimeoutExpired:
    import sys #don't need this here, if you have imported anywhere above.
    sys.exit(1)
except:
    result = sys.exc_info()
    if p != None:
        p.kill()

此外,subprocess.call函数返回返回码,而不是进程本身,因此尝试在p.kill()内执行except:无效。

演示 -

import sys
try:
    subprocess.call(['python','a.py'],timeout=1)
except subprocess.TimeoutExpired:
    sys.exit(1)

a.py是一个python脚本,循环100000次。