Python: убить или завершить подпроцесс, когда тайм-аут

Я хотел бы как можно быстрее выполнить подпроцесс. Однако иногда процесс занимает слишком много времени, поэтому я хочу его убить. Я использую signal.signal (…), как показано ниже:

ppid=pipeexe.pid signal.signal(signal.SIGALRM, stop_handler) signal.alarm(1) ..... def stop_handler(signal, frame): print 'Stop test'+testdir+'for time out' if(pipeexe.poll()==None and hasattr(signal, "SIGKILL")): os.kill(ppid, signal.SIGKILL) return False 

но когда-нибудь этот код попытается остановить выполнение следующего раунда. Stop test / home / lu / workspace / 152 / treefit / test2for time out / bin / sh: / home / lu / workspace / 153 / squib_driver: не найдено — это следующее исполнение; программа ошибочно останавливает его.

Кто-нибудь знает, как это решить? Я хочу, чтобы вовремя не выполнялся 1 секунда time.sleep (n), часто ждал n секунд. Я не хочу, чтобы я хотел, чтобы он выполнял менее 1 секунды

    5 Solutions collect form web for “Python: убить или завершить подпроцесс, когда тайм-аут”

    Вы могли бы сделать что-то вроде этого:

     import subprocess as sub import threading class RunCmd(threading.Thread): def __init__(self, cmd, timeout): threading.Thread.__init__(self) self.cmd = cmd self.timeout = timeout def run(self): self.p = sub.Popen(self.cmd) self.p.wait() def Run(self): self.start() self.join(self.timeout) if self.is_alive(): self.p.terminate() #use self.p.kill() if process needs a kill -9 self.join() RunCmd(["./someProg", "arg1"], 60).Run() 

    Идея заключается в том, что вы создаете поток, который запускает команду, и убивает ее, если таймаут превышает некоторое подходящее значение, в этом случае 60 секунд.

    Вот что я написал в качестве сторожевого пса для выполнения подпроцесса. Я использую его сейчас много, но я не настолько опытен, поэтому, возможно, в нем есть некоторые недостатки:

     import subprocess import time def subprocess_execute(command, time_out=60): """executing the command with a watchdog""" # launching the command c = subprocess.Popen(command) # now waiting for the command to complete t = 0 while t < time_out and c.poll() is None: time.sleep(1) # (comment 1) t += 1 # there are two possibilities for the while to have stopped: if c.poll() is None: # in the case the process did not complete, we kill it c.terminate() # and fill the return code with some error value returncode = -1 # (comment 2) else: # in the case the process completed normally returncode = c.poll() return returncode 

    Применение:

      return = subprocess_execute(['java', '-jar', 'some.jar']) 

    Комментарии:

    1. здесь тайм-аут сторожевого тайма находится в секундах; но легко изменить все необходимое, изменив значение time.sleep() . Значение time_out должно быть документировано соответствующим образом;
    2. в соответствии с тем, что необходимо, здесь, возможно, более целесообразно поднять какое-то исключение.

    Документация: я немного боролся с документацией модуля subprocess чтобы понять, что subprocess.Popen не блокирует; процесс выполняется параллельно (возможно, я не использую здесь правильное слово, но я думаю, что это понятно).

    Но поскольку то, что я написал, является линейным в его исполнении, мне действительно нужно дождаться завершения команды, чтобы избежать ошибок в команде, чтобы приостановить ночное выполнение скрипта.

    Я предполагаю, что это общая проблема синхронизации в event-ориентированном программировании с потоками и процессами.

    Если вы всегда должны иметь только один подпроцесс, убедитесь, что текущий подпроцесс убит, прежде чем запускать следующий. В противном случае обработчик сигнала может получить ссылку на последний прогон подпроцесса и игнорировать старшего.

    Предположим, что выполняется подпроцесс A. Перед обработкой сигнала тревоги запускается подпроцесс B. Сразу после этого ваш обработчик сигнала тревоги пытается убить подпроцесс. Поскольку текущий PID (или текущий объект подпроцесса) был установлен в B при запуске подпроцесса, B убивается и A продолжает работать.

    Верно ли мое предположение?

    Чтобы сделать код более понятным, я бы включил часть, которая создает новый подпроцесс сразу после части, которая убивает текущий подпроцесс. Это будет ясно, что в любой момент работает только один подпроцесс. Обработчик сигналов мог выполнять как подпроцесс, так и запуск, как если бы это был итерационный блок, который работает в цикле, в этом случае управляемый событиями сигнал тревоги каждые 1 секунду.

    Вот что я использую:

     class KillerThread(threading.Thread): def __init__(self, pid, timeout, event ): threading.Thread.__init__(self) self.pid = pid self.timeout = timeout self.event = event self.setDaemon(True) def run(self): self.event.wait(self.timeout) if not self.event.isSet() : try: os.kill( self.pid, signal.SIGKILL ) except OSError, e: #This is raised if the process has already completed pass def runTimed(dt, dir, args, kwargs ): event = threading.Event() cwd = os.getcwd() os.chdir(dir) proc = subprocess.Popen(args, **kwargs ) os.chdir(cwd) killer = KillerThread(proc.pid, dt, event) killer.start() (stdout, stderr) = proc.communicate() event.set() return (stdout,stderr, proc.returncode) 

    Немного сложнее, я добавил ответ, чтобы решить аналогичную проблему : захват stdout, питание stdin и возможность завершить работу через некоторое время бездействия и / или после некоторой общей продолжительности выполнения.

     
    Interesting Posts for Van-Lav

    «Объекты серии изменяются и не могут быть хешированы»

    Создание списка отдельных элементов списка, умноженных n раз

    Как я могу сделать zip-файл с помощью сглаженной структуры каталогов с помощью Zipfile в Python?

    shutil.rmtree () вызывает исключение WindowsError: доступ запрещен:

    Как изменить тип данных фрейма данных pandas на строку с определенным форматом?

    Можете ли вы добавить параметры в пользовательские действия администратора Django?

    Почему этот оператор if вызывает синтаксическую ошибку

    ValueError: неконвертированные данные остаются: 02:05

    Как изменить цвет фона для заголовка QTreeView (он же QHeaderView)?

    Я пытаюсь построить универсальное колесо, но оно откатывается

    Python PIL неправильно декодирует цвета TIFF (используя неправильное цветовое пространство)?

    Каков предпочтительный способ записи пути к файлу в Python

    Pymongo или Mongodb обрабатывает два равных словаря python как разные объекты. Могу ли я заставить их лечиться одинаково?

    преобразование двоичной строки в float

    Как разбить теги из дерева html

    Python - лучший язык программирования в мире.