1
votes

I try fork child processes and wait them to die.I first fork N child processes and then wait in a loop. But it seems it doesn't wait the child processes to die.It exits the loop altough the childs do not die. Here's my code:

void DistributorSubsystem::Start()
{
        Application::instance().logger().information("Distributor Subsytem start");
        //start all the distributors
        pid_t pid = fork();
        pid_t p;
        for (size_t i=0;i<_distributors.size();++i)
        {
                switch(pid)
                {
                        case -1:
                                perror("fork");
                                exit(-1);
                        case 0:
                                p = getpid();
                                printf("PID=%d\n", p);
                                _distributors[i]->Start();
                                Application::instance().logger().information("End of child");
                                exit(0);
                        default:
                                pid = fork();
                }
        }
        int errno;
        //wait for child processes to die
        while (true)
        {
                int status;
                pid_t done = wait(&status);
                if (done == -1)
                {
                        if (errno == ECHILD) break; // no more child processes
                }
                else
                {
                        if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
                        {
                                std::stringstream s;
                                s<<done;
                                Application::instance().logger().error("pid " + s.str() + " failed");
                                exit(-1);
                        }
                }
        }
        Application::instance().logger().information("All started");
}

Here's the output:

PID=7311 ThriftDistributor instance start: PID=7312 ThriftDistributor instance start: All started Distributor Subsytem uninit

2
What is the purpose of the fork at line 5? - mathk
It is early fork to make the switch statement work first time. However, this is a bug. The program starts one child more than wanted. in the /default:/ statement, /i/ needs to be tested against /distributors.size()/ again [the last child needs one more run through the for loop than the parent process]. - ypnos

2 Answers

2
votes

you created one more child by calling "pid = fork();" in the default section of the "switch". this child will reach the wait() function call and will definitely break and exit. The real parent process will keep on running till all the children exit.

0
votes

You shouldn't declare errno like this in a function.

    int errno;

Include the header file errno.h instead (not sure if this is causing your troubles though).