Heim  >  Artikel  >  Backend-Entwicklung  >  Warum bleibt mein Python-„Unterprozess“ hängen, wenn ich die Ausgabe eines C-Programms mit „for line in iter(process.stdout.readline, \'\‘)“ lese?

Warum bleibt mein Python-„Unterprozess“ hängen, wenn ich die Ausgabe eines C-Programms mit „for line in iter(process.stdout.readline, \'\‘)“ lese?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-18 05:23:02662Durchsuche

Why Does My Python `subprocess` Hang When Reading Output from a C Program Using `for line in iter(process.stdout.readline, '')`?

Python-Unterprozess hängt mit „for line in iter“

In diesem Szenario soll das Python-Skript ein C-Programm ausführen und empfangen seine Ausgabe. Das Skript bleibt jedoch in der Zeile „for line in iter(process.stdout.readline, '')“ hängen.

Das Pufferungsproblem

Das Problem entsteht durch ein Pufferproblem. In C-Programmen wird stdout normalerweise blockgepuffert, wenn die Ausgabe über eine Pipeline weitergeleitet wird. Dies bedeutet, dass die Ausgabe gepuffert wird, bis eine bestimmte Menge geschrieben wird oder ein Zeilenumbruch auftritt.

Im C-Programm gibt jede Iteration der while-Schleife „2000“ aus und ruht eine Sekunde lang. Da keine neue Zeile gedruckt wird, wird die Ausgabe gepuffert.

Für Line in Iter Issue

In Python liest subprocess.stdout.readline() die Standardausgabe des untergeordneten Elements Prozess und gibt eine Zeile zurück. Die „for line in iter()“-Schleife durchläuft die von readline() zurückgegebenen Zeilen.

Da die Ausgabe des C-Programms jedoch aufgrund der Pufferung nicht geleert wird, gibt es zu diesem Zeitpunkt keine Zeilen zum Lesen wo das Python-Skript in die Schleife eintritt. Daher wartet das Skript auf unbestimmte Zeit in dieser Zeile.

Lösungen

Pufferung im C-Programm beheben

  • setvbuf(): Das C-Programm kann setvbuf() verwenden, um die Zeilenpufferung für stdout zu erzwingen. Dadurch wird sichergestellt, dass jede Zeile sofort nach dem Drucken geleert wird.
setvbuf(stdout, (char *) NULL, _IOLBF, 0);
  • stdbuf-Dienstprogramm: Das stdbuf-Dienstprogramm kann verwendet werden, um das C-Programm zu umschließen und zu ändern Pufferverhalten.
stdbuf -oL ./main

Pseudo-TTY

  • Pty-Modul: Das Pty-Modul kann zum Erstellen verwendet werden ein Pseudo-TTY, das dem C-Programm vorgaukelt, es würde interaktiv ausgeführt. In diesem Modus wird die Ausgabe standardmäßig zeilengepuffert.
import pty
master_fd, slave_fd = pty.openpty()
process = Popen("./main", stdin=slave_fd, stdout=slave_fd, stderr=STDOUT,
                bufsize=0, close_fds=True)
  • pexpect-Bibliothek: Die pexpect-Bibliothek bietet eine übergeordnete Schnittstelle für die Arbeit mit ptys.
import pexpect
child = pexpect.spawn("./main")
for line in child:
    print line

Durch die Anwendung einer dieser Lösungen wird das Pufferungsproblem gelöst, sodass das Python-Skript die Ausgabe des C-Programms wie erwartet lesen kann.

Das obige ist der detaillierte Inhalt vonWarum bleibt mein Python-„Unterprozess“ hängen, wenn ich die Ausgabe eines C-Programms mit „for line in iter(process.stdout.readline, \'\‘)“ lese?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn