2016-04-28 1 views
1

La session shell suivante montre le comportement que je vois:appel Subprocess arrêter processus parent Python en mode asynchrone exécuté

[[email protected] python-test]$ cat test.py 
#!/usr/bin/env python 
import subprocess 
from time import sleep 
proc = subprocess.Popen("ffmpeg", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) 
print "Starting process: " + str(proc) 
status = proc.poll() 
while status is None: 
    print "Process still running." 
    sleep(0.01) 
    status = proc.poll() 
print "Status: " + str(status) 
[[email protected] python-test]$ python test.py 
Starting process: <subprocess.Popen object at 0x7f2893f27150> 
Process still running. 
Process still running. 
Status: 1 
[[email protected] python-test]$ python test.py & 
[4] 6976 
[[email protected] python-test]$ Starting process: <subprocess.Popen object at 0x7ffa0ea82150> 
Process still running. 
Process still running. 
[4]+ Stopped     python test.py 
[[email protected] python-test]$ ps 
    PID TTY   TIME CMD 
4684 pts/101 00:00:00 python 
4685 pts/101 00:00:00 ffmpeg 
7183 pts/101 00:00:00 ps 
14385 pts/101 00:00:00 bash 

Comme vous pouvez le voir, lorsque le programme Python simple test est exécuté normalement, il termine avec succès. Lorsqu'il est exécuté de manière asynchrone (en utilisant &), le processus Python est arrêté dès que l'appel de sous-processus est terminé (et poll() renvoie une valeur non None).

  1. Le même problème se produit lors de l'utilisation Popen.wait()
  2. Le comportement est unique à ffmpeg.
  3. Le processus Python et ffmpeg s'arrêtent tous deux, comme indiqué dans l'appel à ps.

Quelqu'un peut-il m'aider à démêler ce comportement? Je ne vois rien dans la documentation pour le module subprocess, l'opérateur & de bash, ou ffmpeg qui pourrait expliquer cela.

La version Python est 2.6.6, bash est GNU bash version 4.1.2 (1) -release (x86_64-redhat-linux-gnu), ffmpeg est la version 3.0.1-static.

Nous vous remercions de votre aide!

Répondre

0

J'ai découvert que ffmpeg se bloque lorsqu'il est exécuté de manière asynchrone. Une liste de diffusion a révélé que l'utilisation de nohup évite le problème. Voir here pour ceux qui sont intéressés.

1

Est-ce que la même chose se produit quand shell = False? Vous devrez pointer vers le chemin direct de l'exécutable en utilisant shell = False.

+0

Oui, exactement le même comportement; la tâche synchrone se termine avec succès, la tâche asynchrone est arrêtée avec le processus ffmpeg enfant. – Suriname0

+0

Qu'en est-il de l'utilisation de 'proc.communicate()' à la place de 'proc.poll()'? Supprimez la boucle while et définissez 'status = proc.communicate()' à la place, et récupérez le code retour avec 'proc.returncode'. Notez que 'communicate()' bloque. – 10se1ucgo

+0

Yup, j'ai aussi essayé 'de communiquer()'; même comportement. – Suriname0