Gibt es einen Best-Practices-Ansatz für die Abfrage von stdout/stderr von einem subprocess.Popen
sowie einem zmq-Socket?Interleaving stdout von Popen mit Nachrichten von ZMQ recv
In meinem Fall habe ich mein Hauptprogramm einen Popen Subprozess erzeugen. Der Subprozess veröffentlicht Nachrichten über zmq, die ich dann in meinem Hauptprogramm abonnieren möchte.
Warten auf mehreren ZMQ Buchsen nicht mit der zmq.Poller
kompliziert, aber wenn ich das mit der Ausgabe von meinem subprocess verschachteln wollen selbst, ich bin nicht sicher, wie es in der besten Art und Weise zu tun, ohne wartet oder mit unnötigen Schleifen zu riskieren.
Am Ende würde Ich mag es zu benutzen, wie so:
process = Popen([prog, '--publish-to', 'tcp://127.0.0.1:89890'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, ...)
for (origin, data) in interleave(process, 'tcp://127.0.0.1:89890'):
if origin == 'STDOUT': pass
if origin == 'STDERR': pass
if origin == 'ZMQ': pass
prog --publish-to tcp://127.0.0.1:89890
wird dann eine zmq.PUB
Buchse öffnen und Daten veröffentlichen, während die Verschachtelung Funktion dieser subscribe wird und abfragen auch für stdout und stderr , yield
, welche Daten auch immer zuerst eingehen.
Ich weiß, wie man interleave
mit mehreren Daemon-Threads und Warteschlangen definiert, aber ich weiß nicht, ob dieser Ansatz einige Vorbehalte in Bezug auf Lazy lesen (dh. Stdout möglicherweise nicht bis zum Ende des Programms verarbeitet werden?) oder andere Dinge, über die ich noch nicht nachgedacht habe (das scheint für eine solche Aufgabe auch ziemlich viel Overhead zu sein).
Ich werde für alle Ideen oder Erkenntnisse dankbar sein.
Ich ziele zumindest auf Python 3.3/3.4, aber wenn dies mit den neuen async/await-Tools viel einfacher wird, könnte ich auch Python 3.5 für den Code verwenden.
Sie können den Integer-Dateideskriptor mithilfe von 'process.stdout.fileno()' abrufen. Wenn Sie den Dateideskriptor des zmq-Sockets abrufen können, können Sie einen Aufruf 'select.select ((fd1, d2, fd3),(),(), None)' ausführen, um auf den ersten Aufruf zu warten. Wenn es keine Möglichkeit gibt, den Dateideskriptor des zmq-Sockets abzurufen, können Sie zwei oder drei Threads erstellen, die beide aus einer Quelle lesen (und blockiert werden) und gelesene Daten in eine "Warteschlange" stellen. – pts
Hmm, wird "Auswahl" auch auf Windows funktionieren? Das wäre leider ein Stopper. – Debilski
Siehe auch: http://StackOverflow.com/Questions/9448247/zeromq-Zmq-Poller-Stdin – Debilski