web-dev-qa-db-fra.com

Python: utilisation du sondage popen sur le processus d'arrière-plan

J'exécute un long processus (en fait un autre python) en arrière-plan. J'ai besoin de savoir quand il est terminé. J'ai trouvé que Popen.poll() renvoie toujours 0 pour un processus d'arrière-plan. Y a-t-il une autre façon de procéder?

p = subprocess.Popen("sleep 30 &", Shell=True,
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
a = p.poll()
print(a)

Le code ci-dessus n'imprime jamais None.

16
Code Slinger

Vous n'avez pas besoin d'utiliser l'arrière-plan du shell & syntaxe, car subprocess exécutera le processus en arrière-plan par lui-même

Exécutez simplement la commande normalement, puis attendez que Popen.poll Retour not None

import time
import subprocess

p = subprocess.Popen("sleep 30", Shell=True)
# Better: p = subprocess.Popen(["sleep", "30"])

# Wait until process terminates
while p.poll() is None:
    time.sleep(0.5)

# It's done
print "Process ended, ret code:", p.returncode
37
dbr

Je pense que vous voulez les commandes popen.wait() ou popen.communicate(). Communicate récupérera les données stdout et stderr que vous avez mises dans PIPE. Si l'autre élément est un script Python, j'éviterais d'exécuter un Shell=True appeler en faisant quelque chose comme:

p = subprocess.Popen([python.call, "my", params, (go, here)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = p.communicate()
print(stdout)
print(stderr)

Bien sûr, ceux-ci détiennent le thread principal et attendent la fin de l'autre processus, ce qui pourrait être mauvais. Si vous voulez attendre occupé, vous pouvez simplement envelopper votre code d'origine dans une boucle. (Votre code d'origine a imprimé "Aucun" pour moi, btw)

Exemple de wrapping dans une solution en boucle:

p = subprocess.Popen([python.call, "my", params, (go, here)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while p.poll() == None:
    # We can do other things here while we wait
    time.sleep(.5)
    p.poll()
(results, errors) = p.communicate()
if errors == '':
    return results
else:
    raise My_Exception(errors)
11
blackfedora

Vous ne devez pas exécuter votre script avec esperluette à la fin. Parce que Shell bifurque votre processus et renvoie 0 code de sortie.

10
Fedor Gogolev