2015-01-19 3 views
1

код в fork_child.pyКак убить подпроцессы, когда родительский выход в python?

from subprocess import Popen 
child = Popen(["ping", "google.com"], stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
out, err = child.communicate() 

я запустить его из окна терминала, как -

$python fork_child.py 

Из другого окна терминала, если я получаю PID из fork_child.py и убить его с SIGTERM " пинг "не убивают. Как я могу убедиться, что пинг слишком убит, когда fork_child получает SIGTERM?

+0

Вы устанавливаете обработчик ['signal'] (https://docs.python.org/3.4/library/signal.html« Документация модуля сигналов. ») Для' SIGTERM', который убивает подпроцесс ... – Bakuriu

+0

можете ли вы указать мне пример? – arc000

+0

см. Https://docs.python.org/3.4/library/signal.html#example –

ответ

3

Дети не умирают автоматически, когда родительский процесс убит. Они умирают, если:

  • Родитель передает сигнал и ожидает детей, чтобы прекратить
  • Когда ребенок пытается общаться с родителем, например, через STDIO. Это работает только в том случае, если родитель также создал файловые дескрипторы, которые использует ребенок.

signals module contains examples как написать сигнал обработчика.

Так что вам нужно:

  • собрать все ребенок в списке
  • установить обработчик сигнала
  • в обработчике, перебрать все дочерние процессы
  • Для каждого дочернего процесса, вызовите child.terminate() с последующим child.wait()

wait() является н чтобы позволить ОС мусор собирать дочерний процесс. Если вы забудете об этом, вы можете столкнуться с процессами зомби.

+0

Я не получил утверждение - «Это работает, только если родитель также создал дескрипторы файлов, которые использует ребенок». Не могли бы вы рассказать немного? – arc000

+1

Если родительский процесс убит, все его ресурсы закрыты. Если вы создадите дочерний элемент и подключите его дескрипторы stdio к одному из родительского элемента, он все равно сможет выполнить stdio - на ту же консоль, которую использовал родитель. Но родитель может также создавать каналы.Если головка умирает, один конец трубы закрывается. Ребенок все еще держит другой конец. В то время ничего не происходит. Но в следующий раз, когда ребенок пытается прочитать/записать в такой канал, он получает ошибку. –

0

Простой способ, чтобы убить все дерево процессов в оболочке, чтобы убить свою группу т.е. вместо kill $pid, запустить:

$ kill -TERM -$pid 

Примечание: ПИД инвертируется.

Shell создает новую группу процессов для каждой команды (конвейера), поэтому вы не будете убивать невинных наблюдателей.

Если потоки потомков не создают собственные независимые группы процессов; они все умирают.

См. Best way to kill all child processes.

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