comment tuer (ou à éviter) zombie processus sous-processus module
Quand j'ai lancer un script python à partir d'un autre script python à l'aide de la sous-processus module, un zombie processus est créé lorsque le sous-processus "complète". Je suis incapable de tuer ce sous-processus, à moins que je tue ma mère python processus.
Est-il un moyen de tuer le processus secondaire sans tuer le parent? Je sais que je peux le faire en utilisant wait(), mais j'ai besoin d'exécuter mon script avec no_wait().
Vous devez vous connecter pour publier un commentaire.
Pas à l'aide de
Popen.communicate()
oucall()
entraînera dans un processus zombie.Si vous n'avez pas besoin de la sortie de la commande, vous pouvez utiliser
subprocess.call()
:Si la sortie est important, vous devez utiliser
Popen()
etcommunicate()
pour obtenir le stdout et stderr.Popen.poll()
vous pouvez vérifier si le processus est terminé, vous pouvez utilisercommunicate
. De cette façon, vous pouvez garder la simultanéité.call
parce que vous avez besoin d'écrire à stdin du processus, mais vous ne vous inquiétez pas à propos de la sortie?Un zombie n'est pas un processus réel, c'est juste un reste d'entrée dans le processus de la table jusqu'à ce que le processus parent demande à l'enfant de code de retour. Le processus a pris fin et ne nécessite pas d'autres ressources, mais a déclaré processus d'entrée de la table.
Nous avons probablement besoin de plus d'informations sur le processus à exécuter dans afin de les aider réellement plus.
Toutefois, dans le cas où votre programme en Python sait lorsque le processus enfants ont pris fin (par exemple, en atteignant la fin de l'enfant stdout de données), vous pouvez appeler en toute sécurité
process.wait()
:Exemple de sortie:
Sinon, vous pouvez garder tous les enfants dans une liste, et maintenant et puis
.poll
pour leurs codes de retour. Après chaque itération, n'oubliez pas de retirer de la liste des enfants avec des codes de retour différent deNone
(c'est à dire le fini de celles).Si vous supprimez le sous-processus de l'objet, à l'aide de del à force de collecte des ordures, qui sera la cause de la sous-processus de l'objet à supprimer et puis la défunte processus disparaissent sans résiliation de votre interprète. Vous pouvez essayer cela dans le python interface de ligne de commande en premier.
s = subprocess.Popen('exec cat /dev/zero > /dev/null')
, puiskillall cat
puisdel s
→ zombie est toujours là.s.kill()
puisdel s
. Pas de zombie.Si vous utilisez simplement
subprocess.Popen
, vous serez bien - voici comment:Vous pouvez utiliser
.poll()
de l'objet retourné par Popen pour vérifier si il fini (sans attente). Si elle renvoieNone
, l'enfant est toujours en cours d'exécution.Assurez-vous de ne pas garder les références à la Popen objets - si vous le faites, elles ne seront pas nettoyés, si vous vous retrouvez avec des zombies. Voici un exemple:
Dans l'exemple ci-dessus, si vous voulez vous débarrasser des zombies, vous pouvez soit
.wait()
sur chacun des enfants ou.poll()
jusqu'à ce que le résultat n'est pasNone
.De toute façon est bien - on ne garde pas les références, ou à l'aide de
.wait()
ou.poll()
.L'exécution python prend la responsabilité de se débarrasser de zombie processus, une fois que leur processus d'objets ont été nettoyés. Si vous voyez le zombie qui traînent cela signifie que vous avez gardé un objet de processus et ne s'appelle pas attendre, sondage ou de résilier sur elle.
.wait()
,.poll()
ou.terminate()
, ma conjecture est que Peter est correct.Popen()
objets. Il teste si "exécution python prend la responsabilité de se débarrasser de zombie processus, une fois que leur processus d'objets ont été nettoyés". Il ya un certain soutien pour composer avec les zombies:_active
liste,_cleanup()
fonction est appelée depuisPopen()
mais le test montre qu'il n'aide pas sur Python 2.Je ne suis pas sûr de ce que vous voulez dire "j'ai besoin d'exécuter mon script avec no_wait()", mais je pense que cet exemple n'est ce qu'il vous faut. Les processus ne seront pas des zombies pour très longtemps. Le processus parent ne
wait()
sur eux lorsqu'ils sont en fait déjà terminée et donc ils vont rapidement unzombify.La sortie vers la fin ressemble à ceci:
.wait()
pourrait créer des zombies: imaginez que vous avez appelé.wait()
sur un processus qui doit se terminer en une heure et vous avez d'autres 1000 enfants qui devraient sortir en une seconde. boom. vous avez 1000 zombies dans un deuxième qui ne sera pas récolté jusqu'à ce que l'heure passe.Je ne suis pas entièrement sûr de ce que vous entendez par
no_wait()
. Voulez-vous dire que vous ne pouvez pas bloquer en attente pour le processus de finition? En supposant donc, je pense que cela va faire ce que vous voulez:Récemment, je suis tombé sur ce zombie problème à cause de mon script python. Le problème réel est principalement due à la destruction de la sous-processus et le processus parent ne sait pas que l'enfant est mort. Donc, ce que j'ai fait, juste l'ajout de popen.communiquer() après le signal kill des processus enfant de sorte que le processus parent vient à savoir que l'enfant est mort, puis les mises à jour du noyau le pid du childprocess puisque l'enfant n'est plus et donc il n'y a pas de zombies formé maintenant.
PS:un sondage est également une option ici, car il vérifie et transmet sur le statut de l'enfant au parent. Souvent en sous-processus, il est préférable si u utilisation check_output ou appel si u n'a pas besoin de communiquer avec le stdin, stdout et.