繁体   English   中英

Python Subprocess 从 stdout 块读取(实时读取输出)

[英]Python Subprocess reading from stdout blocks (reading output in real time)

我正在尝试使用子进程与应用程序交互。 我已经使用 Popen 创建了该进程,但我无法在不阻塞整个线程的情况下访问输出流。 然而,写入输入流似乎工作正常(使用通信测试它,但是我可能无法使用它,因为我需要实时数据)。

我已经尝试将缓冲区设置为 1,但它似乎不起作用。

我注意到有时如果进程终止,输出会被刷新。 我确实相信这个问题可能是由于没有发生刷新(并且在关闭时,所有数据同时被接收)引起的,但我不确定。

C代码:

#include <stdio.h>
int main()
{
    int testInteger;
    printf("Enter an integer: \n");
    scanf("%d", &testInteger);
    printf("Number = %d",testInteger);
    return 0;
}

Python代码

import subprocess

p = subprocess.Popen("./a.out", stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True, bufsize=1, close_fds=True)

print(p.stdout.read(1)) #This should read E but instead blocks the whole thread!

我已经尝试将缓冲区设置为 1,但它似乎不起作用。

bufsize参数指定管道的缓冲,但您调用的二进制文件有自己的流缓冲,如果二进制文件没有输出到终端,则通常是全缓冲(如果 stdout 是一个术语,则为行缓冲)。

如果将通信通道更改为 stderr(使用 fprintf),则可以观察到这一点。 或者,如果您在printf之后明确地fflush(stdout) 或者,如果您使用setbuf(3) / setvbuf(3)明确更改缓冲配置(警告:这是 UB,除非它在程序启动时立即完成)。

如果您不想修改 C 程序,您也可以使用stdbuf (非常特定于 GNU)来自定义包装二进制文件的缓冲,只需将"./a.out"替换为['stdbuf', '-o0', 'a.out']使用无缓冲标准输出运行a.out

顺便说一句,这种混乱是您可能不想手动编写脚本交互式程序的原因,这就是pexpect存在的原因。

哦,并且stdin通常具有与stdout相同的缓冲,默认情况下(因此在连接到终端时行缓冲,否则完全缓冲)。

管道read()在返回整个输出之前等待子进程终止,因此它会阻塞。

您可以尝试使用readline() ,如read subprocess stdout line by line 中所述

编辑

您的 c 程序可能需要在printf之后fflush(stdout) 如果printf检测到管道,那么即使输出\\n它也可以选择不刷新。

在遇到换行符时 printf 是否总是刷新缓冲区? .

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM