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()
5 Réponses :
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'
Le problème est que Waiterpid () ne prend que un B> 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 code> 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 code> signalera également leur résiliation ...
Le moyen le plus simple serait d'attendre explicitement jusqu'à ce que tous les processus soient effectués.
while multiprocessing.active_children(): pass
OP veut mettre fin lorsque au moins un enfant i> 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.
Définissez simplement un gestionnaire de signal pour sigchld strong>, 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>
@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) code>. 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!
Il est possible d'utiliser La fonction renvoie un tuple avec le PID de l'enfant mort et son code de sortie. P> os.waitpid () code> en passant -1 em> comme premier argument et 0 em> comme le second. p>
attendre () code>. li>
ul>
Vous voudrez peut-être regarder la catégorie autojiningprocess dans la réponse à cette question similaire . P>
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. P>