2015-05-26 9 views
7

Ich versuche einen Python-Prozess zu erstellen, der einige Eingaben liest, verarbeitet und das Ergebnis ausgibt. Die Verarbeitung erfolgt durch einen Subprozess (Stanford's NER), zur Veranschaulichung verwende ich 'cat'. Ich weiß nicht genau, wie viel Ausgabe NER geben wird, also benutze ich einen separaten Thread, um alles zu sammeln und auszudrucken. Das folgende Beispiel veranschaulicht.So erfassen Sie die Ausgabe eines Python-Subprozesses

import sys 
import threading 
import subprocess 

# start my subprocess 
cat = subprocess.Popen(
    ['cat'], 
    shell=False, stdout=subprocess.PIPE, stdin=subprocess.PIPE, 
    stderr=None) 


def subproc_cat(): 
    """ Reads the subprocess output and prints out """ 
    while True: 
     line = cat.stdout.readline() 
     if not line: 
      break 
     print("CAT PROC: %s" % line.decode('UTF-8')) 

# a daemon that runs the above function 
th = threading.Thread(target=subproc_cat) 
th.setDaemon(True) 
th.start() 

# the main thread reads from stdin and feeds the subprocess 
while True: 
    line = sys.stdin.readline() 
    print("MAIN PROC: %s" % line) 
    if not line: 
     break 
    cat.stdin.write(bytes(line.strip() + "\n", 'UTF-8')) 
    cat.stdin.flush() 

Dies scheint gut zu funktionieren, wenn ich Text mit der Tastatur eingeben. Wenn ich jedoch versuche, Eingaben in mein Skript zu pipen (cat file.txt | python3 my_script.py), scheint eine Rennsituation zu entstehen. Manchmal bekomme ich eine korrekte Ausgabe, manchmal nicht, manchmal sperrt es sich. Jede Hilfe wäre willkommen!

Ich benutze Ubuntu 14.04, Python 3.4.0. Die Lösung sollte plattformunabhängig sein.

+0

Jemand sagte mir einmal Doppelrohr ist problematisch, ohne eine gute Lösung zu bieten. –

Antwort

2

th.join() am Ende hinzufügen sonst können Sie den Thread vorzeitig töten, bevor er den Ausgang alle, wenn der Haupt Thread beendet verarbeitet hat: die Haupt-Thread-Daemon-Threads (oder entfernen th.setDaemon(True) statt th.join()) nicht überleben.

+0

Doh, so einfach, und ich habe es verpasst. Vielen Dank! : D Ich werde jedoch den anderen Thread einen Daemon behalten, aber ich werde den Haupt-Thread nach der Hauptschleife schlafen, um dem anderen Thread Zeit zu geben, die Ergebnisse auszugeben. –

+0

@ FlorijanStamenković time.sleep() ist die falsche Sache hier. Sie können den Parameter 'timeout' an' th.join() 'übergeben, wenn der untergeordnete Prozess hängen bleibt. – jfs

+0

J.F., danke für deinen Kommentar. Ich bin mir nicht sicher, ob ich verstehe, wie Join() helfen wird. Hier ist warum: –

Verwandte Themen