Как я могу получить сигнал, когда Popen заканчивается? - PullRequest
2 голосов
/ 11 июля 2011

в python, у меня есть порожденный процесс оболочки, который я могу остановить вручную, или он может завершиться сам, когда захочет. Могу ли я получить уведомление о том, что оно завершено, не опрашивая его все время?

class Foo(object):

  def __init__(self):
    self.running = False

  def start(self):
    import os
    from subprocess import Popen, PIPE
    self.proc = Popen(['foo'], stdout=PIPE, shell=True, preexec_fn=os.setsid)
    self.running = True

  def stop(self):
    if not self.running:
      print 'already stopped'
    else:
      import os, signal
      os.killpg(self.proc.pid, signal.SIGINT)
      self.on_complete()

  def on_complete(self):
    self.running = False

конструкция более или менее похожа на вышеприведенную. Моя проблема в том, что если процесс был завершен нормально, а не моим собственным прерыванием, то self.running остается True, поэтому я не могу полагаться на этот атрибут для другой логики в классе.

существует ли простой способ вызвать on_complete в случае нормального завершения или это глупый замысел?

1 Ответ

3 голосов
/ 11 июля 2011

Вы должны иметь возможность установить обработчик для SIGCHLD. Внимательно прочитайте документацию; регистрируя интерес к этому сигналу, вы обязуетесь обрабатывать дочерние процессы в обработчике сигнала; все, что wait s в самом подпроцессе будет блокироваться до тех пор, пока все работающие дочерние элементы не будут обработаны обработчиком сигнала, а затем произойдут ошибки. Это включает в себя system() и Popen собственную очистку подпроцесса. (См. Popen.communicate (): OSError: "[Errno 10] Нет дочерних процессов" , например.)

...