C プログラムの出力、つまり "2000" を読み取ろうとするとサブプロセスを使用する Python スクリプトから「」を実行すると、スクリプトが「for 行」でハングします。 iter(process.stdout.readline, '')" 行。この問題は、C プログラムが「2000」を出力し続け、終了状態に到達しないにもかかわらず発生します。
この問題は、ブロック バッファリングの問題が原因です。デフォルトでは、パイプ経由で実行される C プログラムの stdout (たとえば、subprocess.Popen を使用する場合) はブロック バッファリングされます。これは、バッファがいっぱいになるか明示的にフラッシュされるまで、データはパイプにフラッシュされないことを意味します。
オプション 1: C プログラムを直接変更する
この問題を解決するには、 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; }
オプション2: stdbuf ユーティリティを使用します
または、stdbuf ユーティリティを使用して、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()
オプション 3: 使用する擬似 TTY
別のアプローチには、疑似 TTY を使用して C プログラムを騙し、対話的に実行していると思わせます:
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
オプション 4: pexpect を使用します
Pexpect は、疑似 TTY を簡素化する高レベルのインターフェイスを提供します。 -TTY 処理:
import pexpect child = pexpect.spawn("./.main") for line in child: print(line) child.close()
以上が継続的に書き込みを行う C プログラムからの読み取り時に Python `subprocess.readline` がハングするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。