2

環境: gcc4.4.6を使用するx86_64上のLinux2.6.32(RHEL 6.3)

背景:私はいくつかの重いデータ処理を実行しています:〜2000ファイルに広がる〜500GBの入力データ。私のメインプロセスはN個の子をフォークし、それぞれがクランチするファイル名のリストを受け取ります。

私が欲しいのは、コンソールI/Oが親を通過することです。私は、読むべきエラーメッセージが表示されるまで、親ブロックを使用するためにpipe()使用することについていくつかの魅力的なものを調べて見ています。poll()N本のパイプ(子供ごとに1本)がpoll()必要で、聞きたい信号に関する情報を渡す必要があるようです。また、私がそれぞれの子供に入ると、それぞれの子供はいつものようにパイプに書き込むことができるはずだと思いますよね?dup2(pipe[1], STDOUT)cout << stuff;

最初に、私が複数のパイプについて上で言ったことは正しいpoll()ですdup2()か?

次にpoll()、すべての子が死んだら次に進むように親ループを設定するにはどうすればよいですか?

現在、コードのこの(不完全な)セクションは次のようになっています。

int status;
while (1) { // wait for stuff
    while ((status = poll(pollfds, ss.max_forks, -1)) > 1)
        cout << "fork "<< status << ": " << pipes[status][0];
    if (status == -1)   Die(errno, "poll error");
    if (status == 0) { // check that we still have at least one open fd
        bool still_running = false;
        for (int i=0; i<ss.max_forks; i++) {
             // check pipe i and set still_running if it is not zero
        }
        if (!still_running)
            break;
    }
}

第三に、何を設定し、いつfcntl()で設定する必要がありますか?O_ASYNCを実行しますか?ブロッキングまたは非ブロッキングを実行しますか?

4

2 に答える 2

2

実際には、両方のプロセス (親と子) のそれぞれの「未使用」側を close() して、「壊れたパイプ」が確実に発生するようにする必要があります。したがって、子が Pipe[0] に書き込むと、親は Pipe[1] から読み取り、自身の Pipe[0] を閉じます。同様に、子は Pipe[1] を閉じます。

これを行うと、子が死亡した後に親がパイプから読み取るときにエラーが発生します。停止したプロセスをクリーンアップするために、waitpid() スタイルの関数の 1 つを使用することを忘れないでください。

ハンドルをノンブロッキングに設定したい場合があるので、恐ろしく非効率的な 1 バイト読み取りを使用することなく、そこにあるものを読み取ることができます。適切なバッファサイズ (通常は 1024 または 4096) で read() を 1 回呼び出すだけですが、さらにデータがある場合は次のポーリングをトリガーします。しかし、私は通常、数百人ではなく、1人の子供と一緒に仕事をしています:-)

ループに関しては、各子の状態を追跡し、生きている子がなくなったら終了する必要があります。

EDIT:実際には、POLLINが設定されていても0バイトの読み取りを取得した場合、またはPOLLERRまたはPOLLHUPフラグを取得した場合、子が死んでいると想定しています。どのケースが正しいのかわかりません...

于 2012-09-19T20:03:25.580 に答える
1

select()ここにvsに関する質問がありますpoll(): poll と select の違いは何ですか?

しかし、プロセスを分離するのではなく、スレッドを使用することを考えたことはありますか? スレッドとの対話をより細かく制御でき、通信はパイプライン化された I/O ストリームではなくデータ構造を介して行われます。パイプラインは高価です。あなたはOSを通過しており、出力用に結果をフォーマットする/入力時に結果を解析する必要があり、これも高価です。

最後にもう 1 つ: 軽量スレッドを使用しているか、重量のある fork/exec を使用しているかに関係なく、2000 CPU マルチプロセッサを使用していない限り、一度に 2000 個のスレッドを起動することは望ましくありません。CPU の数よりも多くのスレッド/プロセスが CPU をめぐって競合している場合、非常に高価で継続的なコンテキスト スワッピングの状況が発生します。

于 2012-09-19T21:37:52.030 に答える