8

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

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

然后父进程再次循环,等待每个进程终止。随着每个进程终止,我正在尝试注销进程的 pid 和 childid,但这是我遇到麻烦的地方。pid 按顺序打印,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);   
}

免责声明,这是作业(此处的链接,可能随时消失),但我已经完成了几乎所有工作。我只是难以掌握它的这一方面。

4

2 回答 2

4

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

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

于 2013-05-24T20:24:26.507 回答
2
for (int i = 0; i < n; i++)
{
    pid_t pid = PIDs[i];
    int status = NULL;
    waitpid(pid, &status, 0);

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

你想知道为什么要按顺序报告?

将 -1 传递给waitpid该页面说这将导致它等待任何子线程而不是特定线程。

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

于 2013-05-24T20:25:33.020 回答