从标准块读取Python子进程(实时读取输出)

2024-09-30 01:31:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用子流程与应用程序交互。 我已经使用Popen创建了这个进程,但是如果不阻塞整个线程,我就无法访问输出流。 然而,写入inputstream似乎工作得很好(使用Communication对其进行了测试,但是我以后可能无法使用它,因为我需要实时数据)

我已经尝试将缓冲区设置为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!

Tags: 数据代码true应用程序read进程stdout流程
2条回答

I have already tried putting the buffer to 1 but it doesnt seem to work.

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

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

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

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

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

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

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

编辑

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

详见Does printf always flush the buffer on encountering a newline?

相关问题 更多 >

    热门问题