首頁 > 後端開發 > Python教學 > 為什麼我的 Python `subprocess.readline` 在讀取連續編寫的 C 程式時會掛起?

為什麼我的 Python `subprocess.readline` 在讀取連續編寫的 C 程式時會掛起?

Linda Hamilton
發布: 2024-11-19 16:09:03
原創
599 人瀏覽過

Why Does My Python `subprocess.readline` Hang When Reading from a Continuously Writing C Program?

Python 子程序readline 掛在「for line in iter」

問題

當嘗試讀取C 程式的輸出時,即「2000 ,」來自使用subprocess 的Python 腳本,該腳本掛在「for line in iter(process.stdout.readline, '')」行。儘管 C 程式不斷列印「2000」並且從未達到結束狀態,但還是會發生這種情況。

問題源自於區塊緩衝問題。預設情況下,透過管道運行的 C 程式中的 stdout(例如,當使用 subprocess.Popen 時)是塊緩衝的。這意味著在緩衝區已滿或明確刷新之前,資料不會刷新到管道。

選項1:直接修改C 程式

要解決此問題,您可以強制stdout 在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 處理:

import pexpect

child = pexpect.spawn("./.main")
for line in child:
    print(line)
child.close()
登入後複製

以上是為什麼我的 Python `subprocess.readline` 在讀取連續編寫的 C 程式時會掛起?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板