Frage

ich eine allgemeine Frage zu popen (und alle damit verbundenen Funktionen), die für alle Betriebssysteme, wenn ich einen Python-Skript oder einen C-Code und führen Sie die ausführbare Datei aus der Konsole (gewinnen oder Linux) schreibe, kann ich sofort siehe die Ausgabe von dem Prozess. Allerdings, wenn ich laufe die gleiche ausführbare Datei als ein gegabelter Prozess mit seinem stdout in ein Rohr umgeleitet, irgendwo die Ausgangspuffer, in der Regel auf 4096 Bytes, bevor es auf das Rohr geschrieben wird, in dem der übergeordneten Prozess gelesen werden kann.

Der folgende Python-Skript ausgegeben in Blöcken von 1024 Bytes erzeugen

import os, sys, time

if __name__ == "__main__":
     dye = '@'*1024
     for i in range (0,8):
        print dye
        time.sleep(1)

Der folgende Python-Skript, das vorherige Skript ausführen und die Ausgabe so schnell lesen, wie es auf das Rohr, Byte für Byte kommt

import os, sys, subprocess, time, thread

if __name__ == "__main__":
    execArgs = ["c:\\python25\\python.exe", "C:\\Scripts\\PythonScratch\\byte_stream.py"]

    p = subprocess.Popen(execArgs, bufsize=0, stdout=subprocess.PIPE)
    while p.returncode == None:
        data = p.stdout.read(1)
        sys.stdout.write(data)
        p.poll()

Stellen Sie den Pfad für Ihr Betriebssystem. Wenn in dieser Konfiguration ausführen, wird die Ausgabe erscheint nicht in Blöcken von 1024 aber Stücken von 4096, trotz der Puffergröße des popen Befehls auf 0 gesetzt wird (die Standardeinstellung ist sowieso). Kann mir jemand sagen, wie dieses Verhalten ändern ?, ist es eine Möglichkeit, das Betriebssystem zwingen kann, den Ausgang von dem gegabelten Prozess in der gleichen Art und Weise, wie zu behandeln, wenn sie von der Konsole ausgeführt wird ?, dh nur die Daten durchschlagen ohne Pufferung?

War es hilfreich?

Lösung

Im Allgemeinen ist die Standard-C-Laufzeitbibliothek (das ist auf jedem System im Namen von fast jedem Programm ausgeführt wird, mehr oder weniger ;-) erkennt, ob stdout ein Terminal ist oder nicht; wenn nicht, es puffert die Ausgabe (das ist eine große Effizienz zu gewinnen, im Vergleich zu ungepufferten ausgegeben werden kann).

Wenn Sie die Kontrolle über das Programm sind, die das Schreiben tut, können Sie (als eine andere Antwort vorgeschlagen) bündig stdout kontinuierlich, oder (elegant, wenn möglich) versuchen stdout zu zwingen ungepufferte zu sein, z.B. von Python mit dem -u Kommandozeilen-Flag ausgeführt werden:

-u     : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)
         see man page for details on internal buffering relating to '-u'

(was der Mann Seite hinzufügt, ist eine Erwähnung von stdin und Problemen mit Binär-Modus [s]).

Wenn Sie nicht oder wollen nicht, das Programm berühren, die, -u oder dergleichen auf dem Programm schreiben, das gerade liest unwahrscheinlich ist, zu helfen (die Pufferung, dass die meisten zählt, ist der auf dem Schreib stdout geschieht, nicht das auf den Leser stdin). Die Alternative ist, den Schriftsteller dazu zu verleiten, zu glauben, dass es zu einem Terminal schreibt (obwohl in der Tat zu einem anderen Programm sie schreibt!), Über das pty Standardbibliotheksmodul oder übergeordneten Dritten pexpect Modul (oder, für Windows, das Port wexpect ).

Andere Tipps

Das ist richtig, und gilt sowohl für Windows und Linux (und möglicherweise andere Systeme), mit popen() und fopen(). Wenn Sie die Ausgabepuffer vor 4096 Bytes geschickt werden sollen, verwenden fflush() (auf C) oder sys.stdout.flush() (Python).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top