web-dev-qa-db-ja.com

親が実行を再開する前にすべての子プロセスを待機しているUNIX

私のプログラムでは、有限のwhileループで子プロセスを(並列に)フォークし、それぞれに対してexecを実行しています。すべての子が終了した後でのみ、親プロセスが実行を再開するようにします(このwhileループの後のポイント)。どうすればいいですか?

私はいくつかのアプローチを試しました。 1つのアプローチでは、whileループの後に親を一時停止し、waitpidがエラーECHILD(子が残っていない)を返したときにのみSIGCHLDハンドラーから条件を送信しましたが、このアプローチで直面している問題は、親がすべてのプロセスのフォークを完了する前でも、retStatは-1

    void sigchld_handler(int signo) {
        pid_t pid;
        while((pid= waitpid(-1,NULL,WNOHANG)) > 0);
        if(errno == ECHILD) {
            retStat = -1;
        }
    }

    **//parent process code**
    retStat = 1;
    while(some condition) {
       do fork(and exec);
    }

    while(retStat > 0)
        pause();
//This is the point where I want execution to resumed only when all children have finished
13
avd

シグナルハンドラーでwaitpidを呼び出す代わりに、次のようにすべてのプロセスをフォークした後にループを作成してみませんか。

_while (pid = waitpid(-1, NULL, 0)) {
   if (errno == ECHILD) {
      break;
   }
}
_

プログラムは、子がなくなるまでループでハングする必要があります。その後、それは脱落し、プログラムは続行されます。追加のボーナスとして、子が実行されている間、ループはwaitpidでブロックされるため、待機中にビジーループは必要ありません。

wait(NULL)と同等のwaitpid(-1, NULL, 0)を使用することもできます。 SIGCHLDで他に何もする必要がない場合は、SIG_IGNに設定できます。

21
Jeremy Bourque

waitpid()呼び出しを使用する必要があると思います。それはあなたが「どんな子プロセス」を待つことを可能にするので、あなたがそれを適切な回数行うならば、あなたは金色になるはずです。

それが失敗した場合(保証についてはよくわかりません)、ループに座って、各子PIDでNOHANGオプションを指定してwaitpid()を実行し、力ずくのアプローチを実行できます。その後、しばらく遅延してから再度実行します。

0
unwind