Как мне узнать, когда умер процесс ребенка? - PullRequest
6 голосов
/ 09 сентября 2010

В моем классе я запускаю 4 процесса.

from multiprocessing import Process

    procs = (
             Process(target=ClassOne, name='ClassOne'),
             Process(target=ClassTwo, name='ClassTwo'),
             Process(target=ClassThree, name='ClassThree'),
             Process(target=ClassFour, name='ClassFour'),
            )

    for p in procs:
        p.daemon = False
        p.start()

Я бы хотел получить уведомление о смерти одного из моих детей, чтобы я мог убить другого и себя.

Ответы [ 5 ]

3 голосов
/ 09 сентября 2010

Можно использовать os.waitpid(), передавая -1 в качестве первого аргумента и 0 в качестве второго аргумента.

  • Первый аргумент означает, что запрос относится к любому дочернему элементу текущего процесса.
  • Второй аргумент означает, что он ведет себя как wait().

Функция возвращает кортеж с идентификатором мертвого ребенка и его кодом выхода.

3 голосов
/ 09 сентября 2010

Просто определите обработчик сигнала для SIGCHLD , осмотрите фрейм, возвращенный только что умершим потомком, чтобы получить необходимую вам информацию об этом ... и, если необходимо, выйдите из (тоже) родителя:)

1 голос
/ 09 сентября 2010

Самый простой способ - явно дождаться завершения всех процессов.

while multiprocessing.active_children():
    pass

Это не управляемое событиями, как вы могли бы подумать, но оно выполнит работу в вашем примере. Также убедитесь, что вы import multiprocessing.

0 голосов
/ 18 февраля 2011

Вы можете посмотреть на класс AutoJoiningProcess в ответе на этот похожий вопрос .

Если вы готовы добавить в свой код зависимость от gobject (часть PyGTK) тогда AutoJoiningProcess позволит вам прослушивать сигнал, который излучается при завершении процесса.На этот сигнал вы можете ответить, как захотите.

0 голосов
/ 09 сентября 2010

Вот решение для Windows. Он использует WaitForMultipleObjects вызов API. Для Unix os.waitpid может выполнять эту работу.

import multiprocessing as mp
import ctypes


SYNCHRONIZE = 0x00100000
INFINITE = -1


def mbox(msg):
  ctypes.windll.user32.MessageBoxW(0, msg, u'spam', 0)


if __name__ == '__main__':

  # start 2 processes
  procs = [mp.Process(target=mbox, args=(msg,)) for msg in u'ab']
  for p in procs:
    p.start()

  # wait for at least one process to terminate
  handles = [
    ctypes.windll.kernel32.OpenProcess(SYNCHRONIZE, False, p.pid)
    for p in procs]
  array_type = ctypes.c_long * len(handles)
  handle_array = array_type(*handles)
  ctypes.windll.kernel32.WaitForMultipleObjects(
    len(handles), handle_array, False, INFINITE)

  # terminate the rest
  for p in procs:
    p.terminate()

  # exit
  print 'done'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...