W moim programie jestem rozwidleniem (równolegle) procesów potomnych w skończonej pętli while i wykonaniem exec na każdym z nich. Chcę, aby proces nadrzędny wznowił wykonywanie (punkt po tej pętli while) dopiero po zakończeniu wszystkich dzieci. Jak mam to zrobić?Oczekiwanie na wszystkie procesy potomne, zanim rodzic wznowi wykonywanie UNIX
Próbowałem kilku podejść. W jednym z podejść, zrobiłem parent pauzę po pętli while i wysłałem pewien warunek z obsługi SIGCHLD tylko wtedy, gdy waitpid zwrócił błąd ECHILD (żadne dziecko nie pozostało), ale problem, z jakim mam do czynienia w tym podejściu jest jeszcze zanim rodzic zakończył rozwidlanie wszystkich procesów, retStat staje się -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
Muszę podać opcję WNOHANG, ponieważ jeśli istnieje wiele dzieci, które dostarczają sygnał SIGCHLD prawie w tym samym czasie, a ponieważ sygnały nie są umieszczane w kolejce w systemie UNIX, jeśli użyję 0, wtedy będę mógł złapać tylko jeden sygnał, wtedy zombie będą zostań w pobliżu. – avd
Wystarczy dodać trochę, -1 sprawdzi przed każdym pid dziecka (może również używać WAIT_ANY dla jasności). – amischiefr
@aditya: Procesy zombie czekają tylko na wywołanie wait() (lub wait_pid()) na nich. Jak tylko to zrobisz, znikną, niezależnie od tego, czy złapałeś sygnał. Tak więc pętla wait() po pętli fork() usunie wszystkie zombie. –