2010-12-29 2 views
2

complètement réécrite en fonction de ma propre enquêteMettre fin en python sous-processus

J'ai un script maître qui exécute un certain nombre d'autres scripts python. Les scripts sont créés

from subprocess import STDOUT, Popen 
from signal import SIGINT 
import shlex 
p = Popen(shlex.split("python somescript.py arg1 arg2"), cwd="../src/somedir", stderr=STDOUT) 

Et se terminent par

p.send_signal(SIGINT) 
p.wait() 

l'intérieur d'eux il y a le code suivant

if __name__ == "__main__": 

    import signal 
    def terminate(*args): 
     raise KeyboardInterrupt 
    signal.signal(signal.SIGINT, terminate) 

    # do some work here 

Chaque script a une fonction ayant

try: 
    # create workers 
except KeyboardInterrupt: 
    # cleanup, wait for the current worker to end, then return 

Tous les travaux décrits comme supposés - le script maître crée les processus, quand son exécution se termine, il leur envoie SIGINT, ils le manipulent de la manière correcte, en quittant gracieusement.

Maintenant, je veux lancer le serveur de développement Django de la même manière.

I modifié le fichier manage.py:

if __name__ == "__main__": 
    import signal 
    def terminate(*args): 
     print 'got SIGINT' 
     raise KeyboardInterrupt 
    signal.signal(signal.SIGINT, terminate) 

    execute_manager(settings) 

La fonction execute_manager après un certain nombre d'appels conduit à un procédé de commande de django comportant le bloc except KeyboardInterrupt avec sys.exit(0). Donc, l'ensemble de l'installation se ressemble.

Le problème: le serveur django n'est pas réellement arrêté, bien que je vois la sortie got SIGINT.

probablement une explication:

On dirait que django fourches manage.py lui-même ou fait quelque chose de semblable; regarder dans Activity Monitor (l'explorateur de processus de l'osx) Je vois 3 processus python démarrés - celui pour le script maître, et, probablement, 2 pour manage.py. À la fin, 2 d'entre eux s'arrêtent (le script maître, et celui auquel j'ai le lien avec p), tandis que le troisième reste en cours de verrouillage du port 8000. Existe-t-il un moyen d'obtenir des sous-processus PID de processus?

+1

Pourquoi n'utilisez-vous pas 'p.kill()'? –

+0

parce que les sous-processus sont de structure spécifique, chacun ayant son gestionnaire pour KeyboardInterrupt et rendant __gracefull__ exit (en attente de terminer les travaux en cours d'exécution, par exemple) – Guard

+0

Quel système d'exploitation utilisez-vous? – mjhm

Répondre

0

Vous pouvez utiliser psutil pour en savoir plus sur les processus enfants, par ex. en pseudo-code:

p = Popen(...) 
pp = psutil.Process(p.pid) 
for child in pp.get_children(): 
    child.send_signal(signal.SIGINT) 

Notez la différence dans les processus lors de l'exécution sans --reload, obtenue en utilisant ps -ef | grep manage.py | grep -v grep:

vinay 7864 7795 9 22:10 pts/0 00:00:00 python ./manage.py runserver 
vinay 7865 7864 16 22:10 pts/0 00:00:00 /usr/bin/python ./manage.py runserver 

par rapport à l'utilisation de l'option --noreload:

vinay 7874 7795 7 22:10 pts/0 00:00:00 python ./manage.py runserver --noreload 
+0

oui, je remarque déjà la différence, mais je ne savais pas comment obtenir la liste des processus enfants. merci, cela a aidé. – Guard

Questions connexes