2015-07-28 3 views
1

Я получил этот кодТаймаут вызова функции, Python

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' является ввод текста для файл "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 и проверьте, является ли его вывод тем, чем он должен быть.

Мне было рекомендовано ознакомиться с разделом 17.5.1 документации библиотеки Python3 для получения информации о том, как реализовать тайм-аут, но не смог понять, как это сделать. И я попробовал некоторые решения по подобным вопросам, но это не сработало.

Любая помощь?

EDIT: Более подробную информацию о функции run ..

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

прог аргумент является строкой, которая указана имя исполняемого файла во временном каталоге. Аргумент args содержит список строк, которые должны использоваться в качестве аргументов командной строки для программы, названной prog. Метод run выполняет программу, поставляя аргументы командной строки. Если программа во время работы считывает со своего стандартного ввода, то этот стандартный ввод берется из аргумента с именем input. Входной аргумент представляет собой список строк; каждая строка представляет собой одну строку ввода текста для чтения программой. Когда метод запуска возвращается, результатом является либо None (для явно успешного завершения), либо строка (в которой указывается причина, по которой программа не выполняется или не завершается успешно). Независимо от того, что возвращается вызовом функции, необходимо проверить как стандартный поток вывода, так и стандартный поток вывода ошибок.

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() 

UPDATE: После некоторой помощи, я получаю ошибку синтаксиса

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:

+0

Вы используете Python 3? –

+0

Да, я использую Python 3 – Shawn

ответ

1

Для Python 3+, вы можете использовать аргумент timeout для subprocess.call, переходящий в таймаут, который вы хотите указать, а затем, если истечение времени истекает до того, как дочерний процесс завершился, подпроцесс завершит дочерний процесс и поднимет 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: ничего не делает.

Demo -

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

Где a.py является питон скрипт, который петли 100000 раз.

+0

Ok, Итак, я использовал код, который у вас есть в первой части вашего ответа, поместил его в слово в слово, но он все еще не выходит из функции. Проигрыватель C имеет бесконечный цикл внутри него. Поэтому я посмотрел на другую часть вашего кода, демо, добавил 'timeout = 5' в мой' p = = subprocess.call (команда, stdin = stream0, stdout = stream1, stderr = stream2) ', оставив меня с 'p = subprocess.call (команда, stdin = stream0, stdout = stream1, stderr = stream2, timeout = 5)' и добавлен 'except subprocess.TimeoutExpired: sys.exit (1)', но он все равно выиграл ' t exit – Shawn

+0

Хм, если вы удалите попытку: кроме: block, есть ли какие-либо исключения, которые происходят? Можете ли вы проверить. –

+0

SCRATCH ЧТО лол, я на самом деле получить неверную синтаксическую ошибку на 'кроме subprocess.TimoutExpired:' – Shawn

Смежные вопросы