Подтвердить что ты не робот

Ожидание всех дочерних процессов до того, как родитель возобновит выполнение UNIX

В моей программе я разворачиваю (параллельно) дочерние процессы в конечном цикле while и выполняю exec для каждого из них. Я хочу, чтобы родительский процесс возобновил выполнение (точка после этого цикла while) только после того, как все дети закончили. Как мне это сделать?

Я попробовал несколько подходов. В одном из подходов я сделал родительскую паузу после цикла while и отправил какое-то условие из обработчика SIGCHLD только тогда, когда waitpid вернул ошибку ECHILD (ни одного оставшегося ребенка), но проблема, с которой я сталкиваюсь в этом подходе, еще до того, как родитель закончил разворачивать все процессы, 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
4b9b3361

Ответ 1

Вместо вызова waitpid в обработчике сигналов, почему бы не создать цикл после того, как вы разветкили все процессы следующим образом:

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

Программа должна висеть в цикле, пока не будет больше детей. Затем он выпадет, и программа продолжится. В качестве дополнительного бонуса цикл будет блокироваться на waitpid, пока дети будут работать, поэтому вам не нужен цикл занятости во время ожидания.

Вы также можете использовать wait(NULL), который должен быть эквивалентен waitpid(-1, NULL, 0). Если вам ничего не нужно делать в SIGCHLD, вы можете установить его в SIG_IGN.

Ответ 2

Я думаю, вы должны использовать вызов waitpid(). Это позволяет вам ждать "любого дочернего процесса", поэтому, если вы делаете это надлежащее количество раз, вы должны быть золотыми.

Если это не удается (не уверены в гарантиях), вы можете сделать подход грубой силы, сидящий в цикле, выполнив waitpid() с опцией NOHANG на каждом из ваших дочерних PID, а затем задерживая перед тем как сделать это снова.