Rumah >pembangunan bahagian belakang >Tutorial Python >Mengapa Python `subprocess.readline` Saya Bergantung Semasa Membaca daripada Program C Menulis Berterusan?
Apabila cuba membaca output program C, iaitu "2000 ," daripada skrip Python menggunakan subproses, skrip digantung pada "for line in iter(process.stdout.readline, '')" baris. Ini berlaku walaupun program C terus mencetak "2000" dan tidak pernah mencapai keadaan tamat.
Masalahnya berpunca daripada isu penimbalan blok. Secara lalai, stdout dalam program C yang berjalan melalui paip (cth., apabila menggunakansubprocess.Popen) ditimbalkan blok. Ini bermakna data tidak disalurkan ke paip sehingga penimbal penuh atau disiram secara eksplisit.
Pilihan 1: Ubah Suai Program C Secara Terus
Untuk menyelesaikan isu, anda boleh memaksa stdout untuk ditimbalkan talian dalam program C:
#include <stdio.h> int main() { setvbuf(stdout, (char *) NULL, _IOLBF, 0); // Make line buffered stdout while (1) { printf("2000\n"); sleep(1); } return 0; }
Pilihan 2: Gunakan stdbuf Utility
Sebagai alternatif, anda boleh menggunakan utiliti stdbuf untuk menukar jenis penimbal tanpa mengubah suai sumber program C:
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()
Pilihan 3: Gunakan Pseudo-TTY
Pendekatan lain melibatkan penggunaan pseudo-TTY untuk menipu atur cara C untuk berfikir ia berjalan secara interaktif:
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
Pilihan 4: Gunakan peexpect
Pexpect menawarkan antara muka peringkat lebih tinggi yang memudahkan pengendalian pseudo-TTY:
import pexpect child = pexpect.spawn("./.main") for line in child: print(line) child.close()
Atas ialah kandungan terperinci Mengapa Python `subprocess.readline` Saya Bergantung Semasa Membaca daripada Program C Menulis Berterusan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!