6

pipe()、fork()、dup()、execve() を使用して子プロセスを生成します。

親から、子の stdin と stdout が閉じるのを待って (つまり、両方で read() が 0 を返す)、waitpid() を実行して終了ステータスを収集しても安全ですか?

または、stdin と stdout を閉じずにプロセスが失敗する可能性はありますか? (したがって、私のプログラムはwaitpidになりません)


明確にするために、次のものが安全かどうかを尋ねています。

while (child_stdin != -1 && child_stdout != -1) {
    poll(...)

    if (got_stdout) {
        n = read(child_stdout);
        if (n >= 0) {
            // do something with output
        } else if (n == 0) {
            child_stdout = -1
        }
    }

    // same for stdin
}

waitpid(child_pid)

または、子が終了する可能性がありますが、read() または write() で 0 を取得することはありません。

poll() するだけで、シグナルは関係ありません。

4

2 に答える 2

6

processaが process を生成bし、 processが process をb生成する場合c(cの孫も同様ですa)bは、 stdout であったファイル記述子のコピーを終了して閉じることができます (おそらくstdoutは、監視してb'sいるパイプの書き込み側です)。そのパイプが開いているので、から SIGCHLD を取得しますが、パイプで EOF を取得しません。言い換えれば、はい、子が終了しても、親はパイプが閉じているのを認識しないということが起こりえます。acab

aまた、パイプの書き込み側がまだ開いているのは、一般的なコーディング エラーです。その場合、bパイプの書き込み側のコピーを終了して閉じることができますが、親はパイプを開いたままにしているため、パイプが閉じていることを認識しません。

于 2012-11-01T17:18:48.670 に答える
2

すべてのファイル記述子は、プロセスの終了時にシステムによって閉じられます。発生する可能性があるのは、フラッシュされていない出力がバッファに格納されていることです。

子プロセスが終了しない場合、親プロセスが永遠に待機し、到達しない可能性がありますwaitpid()

編集:

あなたの子供が終了すると、すべての記述子が閉じられ、最終的に 0 になりますread()(何かがうまくいかなかった場合は -1!)。したがって、次のように変更することをお勧めします。

...
if (n > 0) {
    // do something with output
} else if (n <= 0) {
    child_stdout = -1
}

ただし、次の理由により、コードは終了しません。

if (n >= 0) {  // n > 0 || n == 0
    // ...
} else if (n == 0) {
    // Never reached!
}
于 2012-11-01T17:14:34.630 に答える