7
votes

Comment puis-je savoir quand un processus enfant est mort?

dans ma classe I exécutée 4 processus.

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()


0 commentaires

5 Réponses :


-2
votes

Voici une solution Windows. Il utilise waitformultiPleObjects appel d'API. Pour Unix OS.WAITPID peut faire le travail.

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'


2 commentaires

Le problème est que Waiterpid () ne prend que un PID et bloque jusqu'à ce que le délai d'attente ... WaiTformultiPleObjects () Est-ce que le travail peut gérer de nombreux objets en même temps ... Pouvez-vous fournir un POC Utiliser WaiterPID ()?


@Spi, comme vous l'avez apparemment découvert, WaiterPID peut être utilisé pour attendre "I-net-soin-soin-qui-un" enfant à mourir. Le problème est que vous pouvez avoir d'autres enfants engendrés et Waiterpid signalera également leur résiliation ...



0
votes

Le moyen le plus simple serait d'attendre explicitement jusqu'à ce que tous les processus soient effectués.

while multiprocessing.active_children():
    pass


2 commentaires

OP veut mettre fin lorsque au moins un enfant meurt, pas quand tous meurent.


Cette solution utilisera un processeur pour attendre occupé et ne sera pas une solution à la question indiquée par @Constantin.



3
votes

Définissez simplement un gestionnaire de signal pour sigchld , inspectez le cadre renvoyé par l'enfant juste mort pour récupérer les informations dont vous en avez besoin ... Et si nécessaire, la sortie (), le parent aussi :) / p>


5 commentaires

@SPI, si vous recherchez une solution spécifique à UNIX, vous auriez dû l'avoir indiqué dans la question.


@Constantin, gagne n'a pas de signaux? Je suis vraiment curieux, pas de polémique :)


Windows a une API de signal C, mais ne les utilise pas de manière native. Sous Windows, vous pouvez attendre trivialement sur les poignées de traitement des enfants. Vous attendriez simplement que le premier devienne signalé, puis terminez les autres puis quittez-vous.


Eh bien, je suppose que votre réponse implique quelque chose comme signal.signal (sigchld, gestionnaire) . Mais docs.python.org/library/signal.html dit "sous Windows, signal () ne peut être appelé qu'avec SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV ou SIGTERM. Un ValueError sera soulevé dans tout autre cas. " Pas de sigchld.


@CONSANTIN, vous avez raison et je ne faisais pas l'inverse ... Je vous demandais si et comment les signaux sont traités sur Windows comme je ne le sais pas ... @msalters l'a expliqué très proprement, grâce à lui!



3
votes

Il est possible d'utiliser os.waitpid () en passant -1 comme premier argument et 0 comme le second.

  • Le premier argument signifie que la demande concerne tout enfant du processus en cours.
  • Le deuxième argument signifie qu'il se comporte comme attendre () .

    La fonction renvoie un tuple avec le PID de l'enfant mort et son code de sortie.


0 commentaires

1
votes

Vous voudrez peut-être regarder la catégorie autojiningprocess dans la réponse à cette question similaire .

Si vous êtes prêt à ajouter à votre code une dépendance à GOBJECT (une partie de PYGTK), puis autojiningprocess permettrait que vous puissiez écouter un signal émis lorsqu'un processus se termine. Sur ce signal, vous pouvez alors répondre cependant que vous le souhaitez.


0 commentaires