私のプログラムでは、有限の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
シグナルハンドラーでwaitpid
を呼び出す代わりに、次のようにすべてのプロセスをフォークした後にループを作成してみませんか。
_while (pid = waitpid(-1, NULL, 0)) {
if (errno == ECHILD) {
break;
}
}
_
プログラムは、子がなくなるまでループでハングする必要があります。その後、それは脱落し、プログラムは続行されます。追加のボーナスとして、子が実行されている間、ループはwaitpid
でブロックされるため、待機中にビジーループは必要ありません。
wait(NULL)
と同等のwaitpid(-1, NULL, 0)
を使用することもできます。 SIGCHLDで他に何もする必要がない場合は、SIG_IGNに設定できます。
waitpid()
呼び出しを使用する必要があると思います。それはあなたが「どんな子プロセス」を待つことを可能にするので、あなたがそれを適切な回数行うならば、あなたは金色になるはずです。
それが失敗した場合(保証についてはよくわかりません)、ループに座って、各子PIDでNOHANG
オプションを指定してwaitpid()
を実行し、力ずくのアプローチを実行できます。その後、しばらく遅延してから再度実行します。