c++ - 在 pclose() 之前从 popen()ed FILE* 读取的输出是否完整?
问题描述
pclose()
的手册页说:
pclose() 函数等待相关进程终止并返回由 wait4(2) 返回的命令的退出状态。
我觉得这意味着如果用 type 打开关联的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
显式调用或退出时,可能会发生这种情况。在那之后,什么都不能从你的管道末端流出。获得 EOF 后,您不知道进程是否已终止,但您确实知道它永远不会向管道写入任何内容。
通过调用pclose
您关闭管道的末端并等待孩子的终止。返回时pclose
,您知道孩子已终止。
如果你在pclose
没有得到 EOF 的情况下调用,并且孩子试图将内容写入管道的末端,它会失败(实际上它会得到 aSIGPIPE
并且可能会死)。
这里绝对没有鸡和蛋的情况。
推荐阅读
- python - “Dropout”、“Monte-Carlo Dropout”和“Channel-wise Dropout”有什么区别?
- python - 如何解决“ValueError:支持的目标类型是:('binary','multiclass')。得到了'multiclass-multioutput'。” pyton 3.7 中的错误
- c# - 如何异步等待任务完成
- typescript - 请求 http.put 不要执行
- reactjs - 如何在 react-image-lightbox 中设置图像样式?
- vue.js - 如何动态绑定到组件内的对象属性?
- android - 更改 sharedPreferences 名称后无法获取数据
- azure - 解析值时遇到 Azure ARM 意外字符 [
- swift - 添加两个结构数组
- node.js - Docker 构建在我的机器上工作,但在 Gitlab CI 中不工作