Несколько подпроцессов с тайм-аутами

Я использую рецепт, который полагается на SIGALRM для установки прерывания тревоги – использование подпроцесса модуля с тайм-аутом

Проблема в том, что у меня есть более одного скрипта Python с использованием процесса signal.ALARM для установки тайм-аутов, и вызывается только самый последний сигнал тревоги. Каков хороший способ улучшить это множество функций Python, устанавливающих тайм-ауты?

One Solution collect form web for “Несколько подпроцессов с тайм-аутами”

За исключением простых, быстрых хаков, избегайте SIGALRM. Это очень старый, ограниченный механизм, не подходящий ни к чему более сложному: вы можете установить только один сигнал тревоги и прерывать любой системный вызов в то время, а не только тот, который вы собираетесь прервать.

Гораздо чище использовать тайм-аут, чтобы убить процесс, например:

import subprocess, signal, os, threading, errno from contextlib import contextmanager class TimeoutThread(object): def __init__(self, seconds): self.seconds = seconds self.cond = threading.Condition() self.cancelled = False self.thread = threading.Thread(target=self._wait) def run(self): """Begin the timeout.""" self.thread.start() def _wait(self): with self.cond: self.cond.wait(self.seconds) if not self.cancelled: self.timed_out() def cancel(self): """Cancel the timeout, if it hasn't yet occured.""" with self.cond: self.cancelled = True self.cond.notify() self.thread.join() def timed_out(self): """The timeout has expired.""" raise NotImplementedError class KillProcessThread(TimeoutThread): def __init__(self, seconds, pid): super(KillProcessThread, self).__init__(seconds) self.pid = pid def timed_out(self): try: os.kill(self.pid, signal.SIGKILL) except OSError as e: # If the process is already gone, ignore the error. if e.errno not in (errno.EPERM, errno. ESRCH): raise e @contextmanager def processTimeout(seconds, pid): timeout = KillProcessThread(seconds, pid) timeout.run() try: yield finally: timeout.cancel() def example(): proc = subprocess.Popen(["sleep", "5"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) with processTimeout(1, proc.pid): print proc.communicate() resultcode = proc.wait() if resultcode < 0: print "error: %i" % resultcode if __name__ == '__main__': example() 

В зависимости от того, что вы выбрали, вы можете использовать более светлый сигнал, чем SIGKILL, чтобы очистить процесс тайм-аута после себя.

  • Как захватить SIGINT в Python?
  • Как я могу использовать сигналы в django bulk create
  • Получить имена сигналов из чисел в Python
  • Python: Какова стандартная обработка SIGTERM?
  • Как мне высмеять обработчик сигнала django?
  • это атомарное присвоение переменной python?
  • Как сигнализировать слоты в графическом интерфейсе из другого процесса?
  • Как я могу отправить сигнал из программы python?
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.