2011-04-24 3 views
20

Je me demande si c'est la bonne façon d'exécuter un processus système et se détacher du parent, mais permettant au parent de quitter sans créer un zombie et/ou tuer l'enfant processus. Je suis actuellement à l'aide du module de sous-processus et le faire ...Python spawn sur un sous-processus enfant, détacher, et quitter

os.setsid() 
os.umask(0) 
p = subprocess.Popen(['nc', '-l', '8888'], 
        cwd=self.home, 
        stdout=subprocess.PIPE, 
        stderr=subprocess.STDOUT) 

os.setsid() modifie le groupe de processus, je crois que le processus permet de continuer à fonctionner quand il est sorties de parents, car il ne appartient au même groupe de processus.

Est-ce correct et est-ce une façon fiable d'effectuer cela? Fondamentalement, j'ai un utilitaire de contrôle à distance qui communique via les sockets et permet de démarrer les processus à distance, mais je dois m'assurer que si la commande à distance meurt, les processus démarrés continueront d'être inchangés.

Je lisais sur les doubles-fourchettes et je ne sais pas si cela est nécessaire et/ou subprocess.POpen close_fds en quelque sorte prend soin de cela et tout ce qui est nécessaire est de changer le groupe de processus?

Merci.

Ilya

+0

Jetez un oeil à http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/ http://www.python.org/dev/peps/pep- 3143/# reference-implementation – sehe

Répondre

5

popen sur Unix est done using fork. Cela signifie que vous serez en sécurité avec:

  1. vous exécutez Popen dans votre processus parent
  2. quitter immédiatement le processus parent

Lorsque les sorties de processus parent, le processus de l'enfant est héritée par le init traiter (launchd sur OSX) et continuera à fonctionner en arrière-plan.

Les deux premières lignes de votre programme python ne sont pas nécessaires, cela fonctionne parfaitement:

import os, time 
import subprocess 
p = subprocess.Popen(['nc', '-l', '8888'], 
        cwd="/", 
        stdout=subprocess.PIPE, 
        stderr=subprocess.STDOUT) 

Je lisais double-fourches et ne sais pas si cela est nécessaire

Cette serait nécessaire si votre processus parent continue de fonctionner et que vous devez protéger vos enfants contre la mort avec le parent. This answer montre comment cela peut être fait.

Comment la double fourche fonctionne:

  1. créer un enfant via os.fork()
  2. dans cet appel enfant Popen() qui lance le processus long
  3. enfant de sortie: Popen processus est héritée par init et fonctionne en arrière-plan

Pourquoi le parent doit-il quitter immédiatement? Que se passe-t-il s'il ne sort pas immédiatement?

Si vous laissez le parent en cours d'exécution et que l'utilisateur arrête le processus, par ex. via ctrl-C (SIGINT) ou ctrl-\ (SIGQUIT) puis il tuerait le processus parent et le processus Popen.

Que se passe-t-il si une seconde se termine après le forking?

Puis, au cours de cette période 1s votre processus Popen est vulnérable à ctrl-c etc. Si vous devez être sûr à 100%, puis utilisez la double fork.

+0

Pouvez-vous expliquer pourquoi le parent doit quitter immédiatement? Que se passe-t-il s'il ne sort pas immédiatement? Aussi ce qui constitue "immédiatement"? Que se passe-t-il s'il sort une seconde après avoir forci? – Hubro

+0

@Hubro: J'ai ajouté les réponses à votre question dans ma réponse ci-dessus et j'ai également clarifié quelques points qui ont été mal expliqués. – hansaplast

+0

Ce processus va se bloquer si le processus fils met une grosse sortie dans un tube. Définissez 'stdout = None' si vous ne voulez pas communiquer avec le processus. Pour plus de détails, voir: https://thraxil.org/users/anders/posts/2008/03/13/Subprocess-Hanging-PIPE-is-your-enemy/ –

Questions connexes