Ich habe folgende Problemstellung und hoffe ihr wisst Rat:
Ich habe vor durch ein Python-Skript nebenlaeufig Prozesse zu starten und deren stdout zu tracken ..
(letzteres soll später zur Fortschritts-Ausgabe des jeweiligen Prozesses dienen).
Hierfür benutze ich folgenden Python Code (und eine C++ Test-Anwendung, die für x Sekunden sekundenweise diverse Ausgaben auf stdout ausgibt):
Code: Alles auswählen
#!/usr/bin/env python
import sys
import subprocess
import threading
import Queue
from collections import deque
# //////////////////////////////////////////////
class StdoutTracker(threading.Thread):
# //////////////////////////////////////////////
'''
Helper class to track stdout of spawned processes
'''
def __init__(self, proc):
assert callable(proc.stdout.readline)
threading.Thread.__init__(self)
self._proc = proc
self._queue = Queue.Queue()
def run(self):
for line in iter(self._proc.stdout.readline, ''):
print("pushing line:"+line),
self._queue.put(line)
def eof(self):
return not self.is_alive() and self._queue.empty()
# //////////////////////////////////////////////
# Help function to invoke processes
# //////////////////////////////////////////////
def invokeProcess(cmd, trackerList):
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
stdR = StdoutTracker(proc)
stdR.start()
trackerList.append(stdR)
# //////////////////////////////////////////////
# Main starting point ..
# //////////////////////////////////////////////
if __name__ == '__main__':
trackerList = deque()
invokeProcess(['./qplay', '3', '2600'], trackerList)
invokeProcess(['./qplay', '6', '2139'], trackerList)
while trackerList:
pT = trackerList.popleft()
if not pT.eof():
line = pT._queue.get()
if line:
print("got line from tracker:"+line),
trackerList.append(pT)
Eine Ausgabe nach Start obigen Programmes ist z.B.:
pushing line:2600:1/3
got line from tracker:2600:1/3
pushing line:2600:2/3
pushing line:2600:3/3
pushing line:2139:1/6
got line from tracker:2139:1/6
pushing line:2139:2/6
got line from tracker:2600:2/3
got line from tracker:2139:2/6
pushing line:2139:3/6
got line from tracker:2600:3/3
got line from tracker:2139:3/6
pushing line:2139:4/6
pushing line:2139:5/6
pushing line:2139:6/6
got line from tracker:2139:4/6
got line from tracker:2139:5/6
got line from tracker:2139:6/6
Diese erscheinen jedoch erst nach (!) Ausfuehrungsdauer des jeweiligen Test-Prozesses (also erst nach drei bzw. sechs Sekunden).
Dies liegt sehr wahrscheinlich an der Implementierung der run Methode.
Vermutlich müsste der Test-Prozess in der run-Methode ständig gepollt und dessen stdout-Ausgaben so abgespeichert werden.
Eine korrekte / funktionierende Implementierung hierfür habe ich allerdings nicht hinbekommen.
Korrekt soll hier heissen: ich würde erwarten, dass das Python-Skript die Ausgaben der beiden gestarteten Prozesse im Hauptprogramm "parallel" ausgibt (d.h. sobald Ausgaben verfügbar sind)
und das solange bis alle Test-Prozesse beendet sind.
Ich bin C++ Programmierer und Python-Neuling und würde mich über Tips / Links / Code-Schnippsel sehr freuen.
Vielen Dank.