【问题标题】:Using Forks with waitpid使用带有 waitpid 的分叉
【发布时间】:2013-12-15 12:19:32
【问题描述】:

是否有 3 个子进程和 1 个父进程? 这两个不同的waitpid是做什么的,为什么会有两个?

int main()
{
    pid_t pid;

    int status, counter = 4;
    while(counter > 0)
    {
        pid = fork();
        if(pid)
        {
            counter /= 2;
        }
        else
        {
            printf("%d", counter); /* (1) */
            break;
        }
    }
    if(pid)
    {
        waitpid(-1, &status, 0);
        counter += WEXITSTATUS(status);
        waitpid(-1, &status, 0);
        counter += WEXITSTATUS(status);
        printf(";%d", counter); /* (2) */
    }
    return counter;
}

waitpid 之后的第二个 printf 打印 3、5、6、34、52、61(不包括分号)。 我不确定如何打印两位数。我知道第二个数字可能来自 while 循环中的 printf。

【问题讨论】:

  • 在while循环的printf之前加一个前缀,这样你就可以知道它从哪里开始。
  • 注意有些孩子也会分叉。
  • @egur 怎么样? fork() 仅在 fork 后需要 counter > 0 的一段代码中调用,子 (pid == 0) 会跳出执行 fork() 的循环。
  • 我的错,漫长的一天。没看到休息;
  • @NeilBharatPatel 当我运行你的代码时,我的输出是412;5。请注意,我的输出顺序 (4, 1, 2) 不是您所期望的——尽管这是正常的,您没有控制孩子的同步。如果您在每次打印后刷新输出(fflush,或仅在末尾包含 \n),您将获得更准确(时间)的输出视图,但这可能还不够......真正的同步(等待控制对输出资源的访问的互斥锁)会更好。

标签: c fork waitpid


【解决方案1】:

是的,有 3 个子进程和 1 个父进程。孩子们返回 4、2、1。

要收集所有状态,您可以使用 while 循环:

if(pid)
{
  while (waitpid(-1, &status, 0) != -1) /* ignoring signals, errors */
    counter += WEXITSTATUS(status);
}
return counter;

在这种情况下,父级返回 7。

如果您只使用两个 waitpid() 调用,那么它们可能会返回来自 {4,2,1} 集合的任何一对,例如,{4,1}{2,1},因此父级会相应地打印 ;5;3

由于 stdio 缓冲和fork() 交互,输出可能成倍增加。见printf anomaly after “fork()”

fork() 之前使用fflush() 或在儿童中使用write/_exit

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-06
    • 2021-05-18
    • 2012-09-30
    • 2022-01-21
    • 2015-09-01
    • 1970-01-01
    相关资源
    最近更新 更多