0

我已经有了解决问题的方法,但我正试图弄清楚到底发生了什么。我不知道为什么该解决方案可以解决我的问题。

几天前,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 上轰炸呢?

非常感谢任何帮助我理解的帮助。

4

0 回答 0