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 donetがうまく機能するため、把握するのが難しいバグでした。

追加してコードを変更すると、次のようになります。

    pclose(stream);

return ステートメントの直前に、エラーなしでこれを何度も実行できます。

これが実行されている間にアクティビティモニターを見ると、 がなくても 78 個のプロセスが表示されないことに注意する必要がありますpclose。したがって、これらはプロセスではありません。それらには PID がありません。

私の質問は、ここで何が起こっているのですか? サブプロセスが実行されて何かを出力するだけで、このループが終了した後、すべてがクリーンアップされるという印象を受けました(ところで、他の投稿では誰も言及していませんpclose)。さらに、パイプが同じプロセスまたは stdout ファイルに対して開いたままになっている場合、反復 18 または 27 でパイプが機能するのはなぜですか? 開いてはいけないものがまだ開いているときに、反復 2 を爆撃してみませんか?

私が理解するのを助ける助けがあれば大歓迎です。

4

0 に答える 0