【问题标题】:Print in order of termination?按终止顺序打印?
【发布时间】:2013-05-20 12:33:54
【问题描述】:

我有一个程序,它生成一个随机数 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),但我已经完成了几乎所有工作。我只是无法理解它的这一方面。

【问题讨论】:

    标签: c process fork waitpid


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:
      for (int i = 0; i < n; i++)
      {
          pid_t pid = PIDs[i];
          int status = NULL;
          waitpid(pid, &status, 0);
      

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

      您想知道为什么要按顺序报告它们吗?

      改为将 -1 传递给 waitpidthis page 表示这将导致它等待任何子线程而不是特定线程。

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

      【讨论】:

        猜你喜欢
        • 2018-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-14
        • 1970-01-01
        • 1970-01-01
        • 2019-05-18
        相关资源
        最近更新 更多