Bessere Multithread-Verwendung von Python-Unterprozeß.Popen & communicate ()?

Ich laufe mehrere Befehle, die einige Zeit dauern können, parallel, auf einem Linux-Rechner mit Python 2.6.

Also habe ich subprocess.Popen class und process.communicate() Methode verwendet, um die Ausführung von mulitple Befehlsgruppen zu parametrieren und die Ausgabe sofort nach der Ausführung zu erfassen.

 def run_commands(commands, print_lock): # this part runs in parallel. outputs = [] for command in commands: proc = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) output, unused_err = proc.communicate() # buffers the output retcode = proc.poll() # ensures subprocess termination outputs.append(output) with print_lock: # print them at once (synchronized) for output in outputs: for line in output.splitlines(): print(line) 

An irgendwo anders heißt es so:

 processes = [] print_lock = Lock() for ...: commands = ... # a group of commands is generated, which takes some time. processes.append(Thread(target=run_commands, args=(commands, print_lock))) processes[-1].start() for p in processes: p.join() print('done.') 

Das erwartete Ergebnis ist, dass jeder Ausgang einer Gruppe von Befehlen auf einmal angezeigt wird, während die Ausführung von ihnen parallel erfolgt.

Aber von der zweiten Ausgabengruppe (natürlich wird der Thread, der der zweite wird, aufgrund des Scheduling-Indeterminismus verändert), beginnt er ohne Newlines zu drucken und um Leerzeichen hinzuzufügen, so viele wie die Anzahl der Zeichen, die in jeder vorherigen Zeile gedruckt werden, und das Eingangsecho wird gedreht Off – der Terminalzustand ist "verstümmelt" oder "abgestürzt". (Wenn ich reset Shell-Befehl ausgeben, wird es normal wiederhergestellt.)

Zuerst habe ich versucht, den Grund für die Behandlung von '\r' , aber es war nicht der Grund. Wie du in meinem Code sehe, habe ich es richtig mit splitlines() gehandhabt, und ich bestätigte das mit repr() Funktion, die auf die Ausgabe angewendet wurde.

Ich denke, der Grund ist gleichzeitige Verwendung von Pfeifen in Popen und communicate() für stdout / stderr. Ich habe versucht, check_output Verknüpfung Methode in Python 2.7, aber kein Erfolg. Natürlich tritt das oben beschriebene Problem nicht auf, wenn ich alle Befehlsausführungen und Drucke serialisiere.

Gibt es einen besseren Weg, um Popen zu behandeln und parallel zu communicate() ?

3 Solutions collect form web for “Bessere Multithread-Verwendung von Python-Unterprozeß.Popen & communicate ()?”

Ein Endergebnis, das durch den Kommentar von JFSebastian inspiriert wurde.

http://bitbucket.org/daybreaker/kaist-cs443/src/247f9ecf3cee/tools/manage.py

Es scheint ein Python-Bug zu sein.

Ich bin mir nicht sicher, ob es klar ist, was run_commands eigentlich tun muss, aber es scheint einfach nur eine Umfrage auf einem Unterprozess zu machen, den Rückkehrcode zu ignorieren und in der Schleife fortzufahren. Wenn du zu dem Teil kommst, wo du Druck ausgegeben hast, wie kannst du wissen, dass die Teilprozesse abgeschlossen sind?

In deinem Beispielcode habe ich deine Verwendung von:

 for line in output.splitlines(): 

Um teilweise die Ausgabe von " / r " zu behandeln; Gebrauch von

 for line in output.splitlines(True): 

Wäre hilfreich gewesen

  • Cross-Plattform-Unterprozess mit verstecktem Fenster
  • Verwenden von Python-Unterprozeß, um Stdout zu stdin umzuleiten?
  • Wie man einen Prozess in Python / Django gabelt?
  • Führen Sie eine C # -Anwendung aus dem Python-Skript aus
  • Asynchroner Unterprozess unter Windows
  • Die Datei kann bei der Verwendung von subprocess.call ('dir', shell = True) in Python nicht gefunden werden
  • Python ist die beste Programmiersprache der Welt.