Search code examples
c++posixchild-processwaitpid

Check for exited child processes in POSIX?


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);
}

Solution

  • 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
       }