gpt4 book ai didi

c++ - 从 popen()ed FILE* 读取的输出是否在 pclose() 之前完成?

转载 作者:搜寻专家 更新时间:2023-10-31 01:28:28 26 4
gpt4 key购买 nike

pclose()的手册页说:

The pclose() function waits for the associated process to terminate and returns the exit status of the command as returned by wait4(2).

我觉得这意味着如果关联 FILE*创建者 popen()"r" 类型打开为了阅读 command的输出,那么在对 pclose() 的调用之后之前,您不确定输出是否已完成.但是在pclose()之后, 关闭 FILE*肯定是无效的,所以你怎么能确定你已经阅读了 command 的全部输出? ?

为了举例说明我的问题,请考虑以下代码:

// main.cpp

#include <iostream>
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <sys/types.h>
#include <sys/wait.h>

int main( int argc, char* argv[] )
{
FILE* fp = popen( "someExecutableThatTakesALongTime", "r" );
if ( ! fp )
{
std::cout << "popen failed: " << errno << " " << strerror( errno )
<< std::endl;
return 1;
}

char buf[512] = { 0 };
fread( buf, sizeof buf, 1, fp );
std::cout << buf << std::endl;

// If we're only certain the output-producing process has terminated after the
// following pclose(), how do we know the content retrieved above with fread()
// is complete?
int r = pclose( fp );

// But if we wait until after the above pclose(), fp is invalid, so
// there's nowhere from which we could retrieve the command's output anymore,
// right?

std::cout << "exit status: " << WEXITSTATUS( r ) << std::endl;

return 0;
}

我的问题,如上文所述:如果我们只是确定产生输出的子进程在 pclose() 之后终止了, 我们怎么知道用 fread() 检索到的内容做完了?但是如果我们等到 pclose() 之后, fp无效,所以我们无法再从任何地方检索命令的输出,对吧?

这感觉像是先有鸡还是先有蛋的问题,但我已经看过与上述类似的代码,所以我可能误解了什么。我很感激对此的解释。

最佳答案

TL;DR 执行摘要:我们如何知道使用 fread() 检索的内容是完整的? — 我们有一个 EOF。

当子进程关闭其管道末端时,您会得到一个 EOF。当它显式调用 close 退出时,就会发生这种情况。在那之后,你的 pipe 末端什么都不能出来。收到 EOF 后,您不知道进程是否已终止,但您可以肯定它永远不会向管道写入任何内容。

通过调用pclose,您可以关闭管道的末端等待子进程终止。当 pclose 返回时,您知道子进程已终止。

如果您调用 pclose 而没有得到 EOF,并且子进程试图将内容写入管道的末端,它将失败(实际上它会得到一个 SIGPIPE 可能会死)。

这里绝对没有鸡生蛋还是蛋生鸡的问题。

关于c++ - 从 popen()ed FILE* 读取的输出是否在 pclose() 之前完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52211756/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com