web-dev-qa-db-fra.com

Python engendre un sous-processus enfant, se détache et quitte

Je me demande si c'est la bonne façon d'exécuter un processus système et de se détacher du parent, tout en permettant au parent de quitter sans créer de zombie et/ou tuer le processus enfant. J'utilise actuellement le module de sous-processus et je fais cela ...

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

os.setsid () change le groupe de processus, ce qui, à mon avis, permet au processus de continuer à s'exécuter à la sortie de son parent, car il n'appartient plus au même groupe de processus.

Est-ce correct et est-ce aussi un moyen fiable de le faire?

Fondamentalement, j'ai un utilitaire de contrôle à distance qui communique via des sockets et permet de démarrer des processus à distance, mais je dois m'assurer que si la télécommande meurt, les processus qu'elle a démarrés continuent de fonctionner sans être affectés.

Je lisais sur les doubles fourches et je ne sais pas si c'est nécessaire et/ou un sous-processus.Ouvrir close_fds s'occupe en quelque sorte de cela et tout ce qui est nécessaire est de changer le groupe de processus?

Merci.

Il y a

31
Ilya Sterin

popen sur Unix est fait avec 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 le processus parent se termine, le processus enfant est hérité par le processus init (launchd sous OSX) et s'exécute toujours 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 sur les doubles fourches et je ne sais pas si c'est nécessaire

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

Comment fonctionne la double fourche:

  1. créer un enfant via os.fork()
  2. dans cet appel enfant Popen() qui lance le long processus
  3. exit enfant: Popen le processus est hérité par init et s'exécute 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 exemple via ctrl-C (SIGINT) ou ctrl-\ (SIGQUIT), il tuerait à la fois le processus parent et le processus Popen.

Et s'il sort une seconde après avoir bifurqué?

Ensuite, pendant cette période de 1 s, votre processus Popen est vulnérable à ctrl-c, etc. Si vous devez être sûr à 100%, utilisez le double forking.

11
hansaplast