Je lance un sous-processus avec la commande suivante:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
Cependant, lorsque j'essaie de tuer en utilisant:
p.terminate()
ou
p.kill()
La commande continue de s'exécuter en arrière-plan, alors je me demandais comment puis-je réellement mettre fin au processus.
Notez que lorsque j'exécute la commande avec:
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
Il se termine avec succès lors de l'émission du p.terminate()
.
python
linux
subprocess
kill-process
user175259
la source
la source
cmd
look? Il peut contenir une commande qui déclenche le démarrage de plusieurs processus. Il n'est donc pas clair de quel processus vous parlez.shell=True
fait une grande différence?Réponses:
Utilisez un groupe de processus afin de permettre l'envoi d'un signal à tous les processus des groupes. Pour cela, vous devez attacher un identifiant de session au processus parent des processus générés / enfants, qui est un shell dans votre cas. Cela en fera le chef de groupe des processus. Alors maintenant, lorsqu'un signal est envoyé au leader du groupe de processus, il est transmis à tous les processus enfants de ce groupe.
Voici le code:
la source
os.setsid
n'est pas disponible dans Windows ( docs.python.org/library/os.html#os.setsid ), je ne sais pas si cela peut aider mais vous pouvez regarder ici ( bugs.python.org / issue5115 ) pour un aperçu de la façon de le faire.subprocess.CREATE_NEW_PROCESS_GROUP
rapport avec cela?CREATE_NEW_PROCESS_GROUP
peut être utilisé pour émulerstart_new_session=True
sur Windowsp.kill()
finit par tuer le processus shell etcmd
est toujours en cours d'exécution.J'ai trouvé un correctif pratique en:
Cela entraînera cmd à hériter du processus shell, au lieu d'avoir le shell lancer un processus enfant, qui ne sera pas tué.
p.pid
sera alors l'id de votre processus cmd.p.kill()
devrait marcher.Je ne sais pas cependant quel effet cela aura sur votre pipe.
la source
Si vous pouvez utiliser psutil , cela fonctionne parfaitement:
la source
AttributeError: 'Process' object has no attribute 'get_children
pourpip install psutil
.Je pourrais le faire en utilisant
il a tué le
cmd.exe
et le programme pour lequel j'ai donné la commande.(Sous Windows)
la source
Popen("TASKKILL /F /IM " + process_name)
si vous ne l'avez pas, vous pouvez l'obtenir à partir ducommand
paramètre.Lorsque
shell=True
le shell est le processus enfant et que les commandes sont ses enfants. Donc, toutSIGTERM
ouSIGKILL
va tuer le shell mais pas ses processus enfants, et je ne me souviens pas d'une bonne façon de le faire. La meilleure façon que je puisse penser est d'utilisershell=False
, sinon lorsque vous tuez le processus shell parent, il laissera un processus shell défunt.la source
Aucune de ces réponses n'a fonctionné pour moi, donc je laisse le code qui a fonctionné. Dans mon cas, même après avoir tué le processus avec
.kill()
et obtenu un.poll()
code retour, le processus ne s'est pas terminé.Suite à la
subprocess.Popen
documentation :Dans mon cas, je manquais le
proc.communicate()
après avoir appeléproc.kill()
. Cela nettoie le processus stdin, stdout ... et met fin au processus.la source
Comme l'a dit Sai, le shell est l'enfant, donc les signaux sont interceptés par lui - le meilleur moyen que j'ai trouvé est d'utiliser shell = False et d'utiliser shlex pour diviser la ligne de commande:
Ensuite, p.kill () et p.terminate () devraient fonctionner comme prévu.
la source
cwd
argument àPopen
.ce que je pense que nous pourrions utiliser:
cela ne tuera pas toute votre tâche mais le processus avec le p.pid
la source
Je sais que c'est une vieille question mais cela peut aider quelqu'un qui cherche une méthode différente. C'est ce que j'utilise sur Windows pour tuer les processus que j'ai appelés.
/ IM est le nom de l'image, vous pouvez également faire / PID si vous le souhaitez. / T tue le processus ainsi que les processus enfants. / F force y met fin. si, comme je l'ai défini, est la façon dont vous faites cela sans afficher de fenêtre CMD. Ce code est utilisé en python 3.
la source
Envoyer le signal à tous les processus du groupe
la source
Je n'ai pas vu cela mentionné ici, donc je le mets au cas où quelqu'un en aurait besoin. Si tout ce que vous voulez faire est de vous assurer que votre sous-processus se termine avec succès, vous pouvez le placer dans un gestionnaire de contexte. Par exemple, je voulais que mon imprimante standard imprime une image et que le gestionnaire de contexte garantisse la fin du sous-processus.
Je pense que cette méthode est également multiplateforme.
la source
shell=True
, selon la question? Ce qui n'est pas dans votre code.thread.join()
. J'espère que cela clarifie les choses.