Проверить, нет ли дочерних процессов в POSIX? - PullRequest
0 голосов
/ 08 мая 2011

Я пытаюсь написать программу, которая проверяет наличие дочерних процессов и перезапускает их, если они завершились. Необходимо перезапустить процессы при их выходе, не дожидаясь выхода других процессов. Я немного растерялся. Вот код, который я сделал до сих пор. Это не закончено или правильно, на самом деле. Но, возможно, кто-то может указать мне правильное направление?

for(int ifile = 1; ifile < 4; ifile++){

    child_pid[ifile - 1] = vfork();

    if(child_pid[ifile - 1] == -1){
        cerr << "fork error on " << argv[ifile] << endl;
    }
    else if(child_pid[ifile - 1] == 0){
        execl(argv[ifile], argv[ifile], NULL);
    }
}

for(int index = 0; index < 3; index++){
    do{
        wait_pid = waitpid(child_pid[index], &status, WUNTRACED);
        if(WIFEXITED(status)){
            count++;
            child_pid[index] = vfork();
            if(child_pid[index] == -1){
                cerr << "rescheduled process error" << endl;
                return -1;
            }
            else if(child_pid[index] == 0){
                cout << "Rescheduling " << argv[index + 1] << endl;
                execl(argv[index + 1], argv[index + 1], NULL);
            }
        }
    }while(count != 4);
}

Ответы [ 2 ]

3 голосов
/ 08 мая 2011

Проблема с вашим подходом заключается в том, что вы будете блокировать ожидание до тех пор, пока не погибнет 1-й [0-й] ребенок, а в это время может умереть любой другой.

Вы можете:

(1) Используйте wait () вместо waitpid (). Это обработает любого из потомков, но заблокирует.

(2) опрос мертвых детей с использованием waitpid () и флага WNOHANG во время зацикливания.

(3) Настройте обработчик сигналов и поймайте сигналы SIGCHILD. Поместите цикл waitpid / WNOHANG в ваш обработчик, но сделайте перезапуск за его пределами.

например. Обработчик делает что-то вроде:

   while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) 
   {
        //set a flag or whatever; not wise to fork/exec in handler
   }
2 голосов
/ 08 мая 2011

Я не уверен, почему вам нужна опция WUNTRACED. Там, где написано «Остановлено», я почти уверен, что это означает то же самое, что «приостановлено», а не «завершено».

Два возможных подхода:

Вместо зацикливания просто выполните:

pid_t pid = wait();

будет блокироваться до завершения процесса.

Или измените третий аргумент на waitpid() с WUNTRACED на WNOHANG. Это позволит ему тестировать каждый процесс без блокировки. В этом случае вы можете добавить небольшой сон в конце каждого прохода через цикл.

...