I'm trying to write a program that checks for exited child processes and restarts them if they have exited. It needs to restart the processes as they exit, without waiting for any other processes to have exited. I'm a little lost. Here's the code that I've done so far. It's not finished or correct, really. But perhaps someone can point me in the right direction?
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);
}
The problem with your approach is that you are going to block on waitpid until that 1st [0th] child dies and any of the others may die in the meantime.
You can:
(1) Use wait() instead of waitpid(). This will process any of the children but it will block.
(2) poll for dead children using waitpid() and the WNOHANG flag while looping around.
(3) Set up a signal handler and catch the SIGCHILD signals. Put the waitpid/WNOHANG loop in your handler but do the work of restarting outside of it.
E.G. Handler does something like:
while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0)
{
//set a flag or whatever; not wise to fork/exec in handler
}
I'm not sure why you want the WUNTRACED
option. Where it says "Stopped", I'm pretty sure it means the same as suspended, not exited.
Two possible approaches:
Rather than looping, just do:
pid_t pid = wait();
it will block until a process has finished.
Or, change the third argument to waitpid()
from WUNTRACED
to WNOHANG
. That will let it test each process without blocking. In that case, you might want to add a small sleep at the end of each pass thru the loop.
精彩评论