Heim > Artikel > Backend-Entwicklung > Warum bleibt meine Python-Datei „subprocess.readline' hängen, wenn sie aus einem kontinuierlich schreibenden C-Programm liest?
Beim Versuch, die Ausgabe eines C-Programms zu lesen, nämlich „2000 ,“ aus einem Python-Skript, das einen Unterprozess verwendet, hängt das Skript an der „for“-Zeile in iter(process.stdout.readline, '')" Linie. Dies geschieht, obwohl das C-Programm ständig „2000“ ausgibt und nie einen Endzustand erreicht.
Das Problem ist auf ein Problem mit der Blockpufferung zurückzuführen. Standardmäßig ist stdout in C-Programmen, die über Pipes ausgeführt werden (z. B. bei Verwendung von subprocess.Popen), blockgepuffert. Dies bedeutet, dass Daten erst in die Pipe geleert werden, wenn der Puffer voll ist oder explizit geleert wird.
Option 1: C-Programm direkt ändern
Um das Problem zu beheben, müssen Sie kann erzwingen, dass stdout im C-Programm zeilengepuffert wird:
#include <stdio.h> int main() { setvbuf(stdout, (char *) NULL, _IOLBF, 0); // Make line buffered stdout while (1) { printf("2000\n"); sleep(1); } return 0; }
Option 2: Verwenden Sie stdbuf Dienstprogramm
Alternativ können Sie das Dienstprogramm stdbuf verwenden, um den Puffertyp zu ändern, ohne die C-Programmquelle zu ändern:
from subprocess import Popen, PIPE process = Popen(["stdbuf", "-oL", "./main"], stdout=PIPE, bufsize=1) for line in iter(process.stdout.readline, b''): print(line) process.communicate()
Option 3: Pseudo-TTY verwenden
Ein anderer Ansatz besteht darin, ein Pseudo-TTY zu verwenden, um dem C-Programm vorzutäuschen, dass es läuft interaktiv:
import os import pty import sys from select import select from subprocess import Popen, STDOUT master_fd, slave_fd = pty.openpty() process = Popen("./main", stdin=slave_fd, stdout=slave_fd, stderr=STDOUT, bufsize=0, close_fds=True) timeout = .1 with os.fdopen(master_fd, 'r+b', 0) as master: input_fds = [master, sys.stdin] while True: fds = select(input_fds, [], [], timeout)[0] # Handle subprocess output and user input here
Option 4: Verwenden Sie pexpect
Pexpect bietet eine übergeordnete Schnittstelle, die die Pseudo-TTY-Verarbeitung vereinfacht:
import pexpect child = pexpect.spawn("./.main") for line in child: print(line) child.close()
Das obige ist der detaillierte Inhalt vonWarum bleibt meine Python-Datei „subprocess.readline' hängen, wenn sie aus einem kontinuierlich schreibenden C-Programm liest?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!