#c #posix #child-process #waitpid
#c #posix #дочерний процесс #waitpid
Вопрос:
Я пытаюсь написать программу, которая проверяет наличие завершенных дочерних процессов и перезапускает их, если они завершились. Необходимо перезапускать процессы по мере их завершения, не дожидаясь завершения каких-либо других процессов. Я немного заблудился. Вот код, который я уже сделал. На самом деле это не закончено или не корректно. Но, возможно, кто-нибудь может указать мне правильное направление?
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], amp;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);
}
Ответ №1:
Проблема с вашим подходом заключается в том, что вы собираетесь блокировать waitpid до тех пор, пока этот 1-й [0-й] дочерний процесс не умрет, а любой из других может умереть за это время.
Вы можете:
(1) Используйте wait() вместо waitpid(). Это обработает любой из дочерних процессов, но он будет заблокирован.
(2) опрос на предмет мертвых дочерних процессов с использованием waitpid() и флага WNOHANG во время выполнения цикла.
(3) Настройте обработчик сигналов и перехватывайте сигналы SIGCHILD. Поместите цикл waitpid / WNOHANG в свой обработчик, но выполните перезапуск вне его.
Например, обработчик выполняет что-то вроде:
while ((child_pid = waitpid(-1, amp;status, WNOHANG)) > 0)
{
//set a flag or whatever; not wise to fork/exec in handler
}
Ответ №2:
Я не уверен, зачем вам нужна эта WUNTRACED
опция. Там, где написано «Остановлено», я почти уверен, что это означает то же самое, что приостановлено, а не завершено.
Два возможных подхода:
Вместо зацикливания просто выполните:
pid_t pid = wait();
он будет блокироваться до тех пор, пока процесс не завершится.
Или измените третий аргумент на waitpid()
from WUNTRACED
на WNOHANG
. Это позволит ему тестировать каждый процесс без блокировки. В этом случае вы можете захотеть добавить небольшой режим ожидания в конце каждого прохода через цикл.