按终止顺序打印?

时间:2013-05-24 20:11:02

标签: c process fork waitpid

我有一个生成随机数n的程序,然后循环n次。

在每次迭代中,它随机化sleeptime的值,并调用fork。子进程休眠sleeptime秒,然后使用索引变量的值退出。

然后父进程再次循环,等待每个进程终止。当每个进程终止时,我正在尝试注销进程的pid和childid,但这就是我遇到麻烦的地方。 pids按顺序打印,childid保持为0。

我做错了什么?

int main(int argc, char* argv[])
{

    //  Wire up the timer
    long time = elapsedTime(0);

    /*  Generate a random number between MINFORKS and MAXFORKS
     */
    unsigned int seed = generateSeed(0);
    int n = rand_r(&seed) % MAXFORKS + MINFORKS-1;

    /*  Log next step
     */
    time = elapsedTime(1);
    printf("%li: Number of forks = %i\n", time, n);

    /*  Hang on to the PIDs so we can wait for them after forking
     */
    pid_t *PIDs = (pid_t *)(malloc(sizeof(*PIDs)*n));


    /*  Fork n times
     */
    for (int i = 0; i < n ; i++)
    {
        /*  Call fork() and retain the returned identifier
         */
        pid_t processIdentifier = fork();

        /* Randomize the child sleep time
         */
        seed = generateSeed(0);
        int sleeptime = rand_r(&seed)  % MAXPAUSE + MINPAUSE;

        /*  Check for errors
         */
        if (processIdentifier == -1) {
            printf("Error: %i", errno);
        }


        if (!processIdentifier)
        {
            /*  We're in the child process,
             *  sleep and then exit with
             *  i as the error code.
             */

            usleep(sleeptime);
            _exit(i);
        }
        else
        {
            /*  We're in the parent:
             *  Store the PID and
             *  print out the results.
             */

            PIDs[i] = processIdentifier;

            time = elapsedTime(1);
            printf("%li: Child %i, pid = %i, forked, waits %i usec\n", time,  i, processIdentifier, sleeptime);

        }
    }

    /* Log next step
     */
    time = elapsedTime(1);
    printf("%li: Finished forking, going to wait.\n", time);

    /*
     *  Loop through the processes and wait for them
     *  to terminate. Then print the childid, and the
     *  the pid.
     */

    for (int i = 0; i < n; i++)
    {

        /*  Get the PID we want to track
         */
        pid_t pid = PIDs[i];

        /*  Wait for the child process
         *  and grab it's status info
         */
        int status = NULL;


        waitpid(pid, &status, 0);

        int childid = -1;
        if(WIFEXITED(status))
        {
            childid = WTERMSIG(status);
        }

        /*  Log the results
         */
        time = elapsedTime(1);
        printf("%li: Child %i, pid = %i, terminated\n", time, childid, pid);
    }

    /*  All done!
     */
    time = elapsedTime(1);
    printf("All done. It only took %li milliseconds!", time);   
}

免责声明,这是作业(link here, may disappear at any time),但我已经完成了几乎全部工作。我只是很难理解它的这一方面。

2 个答案:

答案 0 :(得分:4)

您的代码正在按照您在后续waitpid()来电中提供的顺序等待pid。如果您将-1作为第一个参数传递给waitpid()(或者只是调用wait()),您将获得内核通知您的第一个子项,而不是一个你特意要求得到通知。检查返回值以查看它是哪个子项(或者是否发生错误)。

childid保留0,因为您正在从等待状态中提取WTERMSIG,而不是WEXITSTATUS

答案 1 :(得分:2)

for (int i = 0; i < n; i++)
{
    pid_t pid = PIDs[i];
    int status = NULL;
    waitpid(pid, &status, 0);

首先,它等待第一个进程结束,然后打印该进程的信息 然后它等待第二个进程结束,然后打印该进程的信息 然后它等待第三个过程结束......

你想知道他们为什么被按顺序报道?

将-1传递给waitpid,而this page表示将等待任何子线程而不是特定线程。

此外,在打印之前,您有int childid = -1;。不知道为什么。