2016-07-07 18 views
0

Ich habe ein Problem, wo ein Anruf an proc.communicate() immer noch hängt, selbst nach dem Aufruf proc.terminate().Python Subprozess kommunizieren fehlschlägt nach dem Beenden

Ich schaffe Aufgaben im Hintergrund

import subprocess as sub 
p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, shell=False) 

Bei Beendigung des Skripts mit dem Anruf ausgeführt werden, rufe ich terminate(), communicate() und wait() Informationen aus dem Prozess zu sammeln.

Das Skript hängt bei dem Aufruf zu kommunizieren. Ich war davon ausgegangen, dass jeder Anruf, der auf einen Anruf zum Beenden folgt, sofort zurückkehrt. Gibt es einen Grund, warum das scheitern würde?

Edit: Ich verwende diese Methode, weil der Befehl wirklich eine enge Schleife ist, die nicht von selbst beendet wird. Ich würde gerne p.terminate() dazu verwenden und dann sehen, was der stdout und stderr zu bieten hat.

+3

Natürlich haben Sie es gerade beendet, warum rufst du nicht einfach an? –

+0

wenn 'p.wait()' 'kehrt aber p.communicate()' "hängt" dann kann es zu [Python subprocess .check_call vs .check_output] bezogen werden (http://stackoverflow.com/q/36169571/4279) ('check_call()' ruft '.wait()' intern auf, 'check_output()' ruft '.communicate()' intern auf). Unrelated: "p.wait()' muss nicht explizit aufgerufen werden: 'p.wait()' wird sowieso intern aufgerufen und Sie können 'p.returncode' verwenden, nachdem' p.communicate() 'zurückkommt. Im Allgemeinen ist es eine schlechte Übung, 'p.wait()' vor 'p.communicate()' aufzurufen, da es einen Live-Prozess blockieren kann (in diesem Fall trifft das nicht zu - der Prozess ist tot). – jfs

+0

@PadraicCunningham: Es ist nicht so einfach, z. B. was passiert, wenn der Kindprozess nicht beendet wird, bis Sie ihn explizit beenden. Ein anderer Fall: Wenn der Kindprozess seine eigenen Kinder hervorbringt, kann sich 'p.communicate()' verzögern; lies meine Antwort zu [der verknüpften Frage] (http://stackoverflow.com/q/36169571/4279). – jfs

Antwort

1

Sie brauchen nicht die ersten beiden Aussagen. Rufen Sie einfach communicate().

Verwandte Themen