函数调用超时,Python

Timeout in Function Call, Python

我有这个代码

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

其中"prog"是可执行c文件的名称,"-4""prog"使用的命令行参数,'\tab \t cd\n', ' \t ab cd \n', '\ta\b\b\b\tb\n'是文件的输入文本"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。 基本上,我想要这样,如果我的 run 函数花费的时间超过 5 秒,我将调用 Sys.exit(1) 并在那里结束它。

我的 run 函数的正确调用,加上 timeout 参数,应该是

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

我的完整代码的总体思路是编译和执行一个 C 文件并检查它的输出是否是它应该的。

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

有什么帮助吗?

编辑: 有关 run 函数的更多信息..

run(self, prog,args=[],input=[])

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

CompileAndExecute 是 class 名称,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

对于上述块中的代码行,except subprocess.TimeoutExpired:

对于Python 3+,可以对subprocess.call使用timeout参数,传入你要指定的超时时间,然后如果超时时间在子进程之前到期终止,子进程将终止子进程并引发 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 函数 returns 返回代码,而不是进程本身,因此尝试在 except: 中执行 p.kill() 不会执行任何操作。

演示 -

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

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