我已经有了解决问题的方法,但我正试图弄清楚到底发生了什么。我不知道为什么该解决方案可以解决我的问题。
几天前,SO帮我提供了一个结果函数:C++管道系统调用总是以EOF结尾吗?
我在这里重现代码:
string pipeAndGetResults(string cmd)
{
const char* ccmd = cmd.c_str();
FILE* stream = popen( ccmd, "r" );
std::ostringstream output;
while( !feof( stream ) && !ferror( stream ))
{
char buf[128];
int bytesRead = fread( buf, 1, 128, stream );
output.write( buf, bytesRead );
}
string result = output.str();
boost::trim(result);
return result;
}
我发生了最奇怪的错误。我在一个循环中运行它,每次在循环中调用一些具有不同数据的进程。在我的 Ubuntu 机器上,我可以毫无问题地运行 200 或 300 次(从未尝试过更多)。但是,在我的 Mac 上,这个炸弹每次迭代 77 次。这是一个很难弄清楚的错误,因为如果子进程爆炸,popen 确实可以很好地工作,因为无法跨进程捕获异常。
似乎如果我通过附加来修改代码:
pclose(stream);
在 return 语句之前,我可以运行多次而不会出现任何错误。
我需要提一下,如果我在运行时查看活动监视器,即使没有pclose
. 所以这些不可能是过程。他们没有PID。
所以我的问题是,这里发生了什么?我的印象是,如果子进程只是运行并打印一些东西,那么在这个循环退出后一切都会清理干净(顺便说一句,在另一篇文章中没有人提到pclose
)。此外,如果管道对同一进程或标准输出文件保持打开状态,为什么它对迭代 18 或 27 有效?当不应该打开的东西仍然打开时,为什么不在迭代 2 上轰炸呢?
非常感谢任何帮助我理解的帮助。