当子进程不刷新其stdout时,如何从子进程读取stdout

How to read stdout from a subprocess when the latter does not flush its stdout?

本文关键字:子进程 stdout 读取 刷新      更新时间:2023-10-16

在下面的代码之前我做:

  • 创建1个管道以读取分叉进程的输出

  • 分叉()

  • execv()python脚本

然后在父进程中我做:

//set pipes to non-Blocking
File * cout_f = fdopen(cout_pipe[0], "r");
int flags = fcntl(cout_pipe[0], F_GETFL, 0);
fcntl(cout_pipe[0], F_SETFL, flags|O_NONBLOCK);
// read from pipe and send it up through a callback method
int stat;
size_t size = 0;
char buffer [ 1000 ];
do
{
    while((size = fread(buffer, sizeof(char), sizeof(char)*1000, cout_f))!=0)
    {
        call_back_function(buffer, size);
    }
}while(waitpid(child_pid, &stat, WNOHANG) != -1)
//Do 1 extra read
while((size = fread(buffer, sizeof(char), sizeof(char)*1000, cout_f))!=0)
{
    call_back_function(buffer, size);
}

当子进程打印到stdout并在刷新之前退出(正常情况下)时,就会出现我所面临的问题。我想念管道里送来的东西。

以下是我的问题:

  • 以上代码是否安全/正确,或者是否可以改进
  • 有没有一种方法可以在子流程终止的最后一刻读取整个管道,即使它没有刷新stdout

您不必等待。只要在阅读时发送所有内容。这就是您的代码已经做的。摆脱非阻塞模式;摆脱while(等待(…))条件;去掉最后的阅读;并且仅执行第一读取循环直到流结束。然后调用wait()获取退出代码。

如果进程也在stderr上生成,则需要在另一个线程中读取,否则当stderr缓冲区时,它将阻塞。