Nous avons une grande application écrite en Python. Nous souhaitons nettoyer proprement les processus qui ont été lancés par notre application lorsque nous l'avons fermé ou interrompu. Cependant, par le biais du code Python (par exemple subprocess.Popen ou os.system), nous avons une commande A qui lance une autre sous-commande B mais la commande B semble avoir aucune relation avec la commande A. Le processus père de la commande B est le processus init (avec pid 1). Comment tuer le processus B en code Python (par exemple après Ctrl + C)? Par exemple, nous avons 2 scripts shell et un script Python qui appelle ces scripts shell.Comment tuer correctement tous les processus lancés par l'application?
le premier script Shell mycommand1.sh est:
#!/bin/sh
sleep 3600 &
le second script Shell mycommand2.sh est:
#!/bin/sh
sleep 3600
le script python myscript.py est:
import os
import signal
import subprocess
def launchCommands():
proc1 = subprocess.Popen('./mycommand1.sh', stdout=subprocess.PIPE, shell = True, preexec_fn=os.setsid)
print "the processus 1 has started"
proc2 = subprocess.Popen('./mycommand2.sh', stdout=subprocess.PIPE, shell = True, preexec_fn=os.setsid)
print "the processus 2 has started"
return proc1, proc2
if __name__ == '__main__':
proc1 = None
proc2 = None
try:
proc1, proc2 = launchCommands()
while True:
pass
except KeyboardInterrupt:
print "Ctrl+C received! ..."
print "trying to kill the processus 2"
os.killpg(os.getpgid(proc2.pid), signal.SIGTERM)
print "processus 2 has been killed"
print "trying to kill the processus 1"
os.killpg(os.getpgid(proc1.pid), signal.SIGTERM)
print "processus 1 has been killed"
Ensuite, nous exécutons notre script Python et nous l'interrompons après 3 secondes avec un Ctrl + C. Voici la sortie après l'interruption.
$> python myscript.py
the processus 1 has started
the processus 2 has started
^CCtrl+C received! ...
trying to kill the processus 2
processus 2 has been killed
trying to kill the processus 1
Traceback (most recent call last):
File "myscript.py", line 33, in <module>
os.killpg(os.getpgid(proc1.pid), signal.SIGTERM)
OSError: [Errno 3] No such process
Nous proposons tous les processus de « sommeil » pendant et après l'exécution du script Python (Bien sûr, il n'y a pas de processus de sommeil avant l'exécution du script Python).
Pendant l'exécution de la commande myscript.py:
$> ps -ef | grep sleep
501 50700 1 0 2:21 ?? 0:00.00 sleep 3600
501 50701 50699 0 2:21 ?? 0:00.00 sleep 3600
501 50703 410 0 2:21 ttys002 0:00.00 grep sleep
Après avoir interrompu le programme avec les touches Ctrl + C:
$> ps -ef | grep sleep
501 50700 1 0 2:21 ?? 0:00.00 sleep 3600
501 51025 410 0 2:23 ttys002 0:00.00 grep sleep
Comme on le voit, le processus 1, nous essayons de tuer n'existe pas plus et un processus de sommeil dont le père pid est 1 existe toujours. Ce processus de sommeil provient de l'exécution du script mycommand1.sh. Comment tuer correctement ce processus de sommeil dans le script myscript.py (bien sûr, nous ne voulons pas tuer tout le processus de sommeil)?
Je ne peux pas le reproduire. J'ai fait tout ce que vous avez décrit – RedEyed
Merci beaucoup pour votre intérêt pour mon problème. J'ai fait ces expériences sur Mac (macOS Sierra 10.12.3) et ma version de Python est 2.7.13. J'ai copié tous les codes que j'ai écrits dans ma question, je viens d'ajouter des droits pour les scripts shell avant de lancer la commande python (chmod 755 mycommand * .sh) et j'ai bien reproduit le problème. –
Je l'ai testé sur Ubuntu 17, et je ne peux pas le reproduire. Je l'ai également testé sur Python 2.7.13. – RedEyed