【问题标题】:c: how does function waitpid work?c: 函数 waitpid 是如何工作的?
【发布时间】:2016-03-15 11:27:24
【问题描述】:

在学习CSAPP的过程中,我遇到了这样一个做法:列出以下程序所有可能的输出序列:

int main()
{
        if(Fork()==0)   {
                printf("a");
        }
        else {
                printf("b");
                waitpid(-1,NULL,0);
        }
        printf("c");
        exit(0);
}

答案是:acbc abcc bcac bacc;

为什么bcac 正确?函数waitpid() 暂停调用进程的执行,直到其等待集中的子进程终止。所以父进程不能打印c,直到子进程终止,这意味着子进程同时打印ac
我真的很困惑。我不知道为什么bcac 是正确的。父进程应该保持或挂起,直到子进程终止。

【问题讨论】:

  • 你确定是Fork()吗?
  • 可能是由于缓冲。默认情况下,输出到stdoutprintf 正在使用)是行缓冲。直到缓冲区已满(此处不会发生),才会刷新输出,打印换行符(此处不会发生),有明确的fflush 调用(此处不会发生),或者进程退出并输出已冲洗。
  • 可能是另一个副本:stackoverflow.com/q/2530663/694576
  • Fork() : pid_t Fork(void) { pit_t pid; if((pid = fork())
  • C 库提供pid_t fork(void)。请注意大小写。

标签: c


【解决方案1】:

正如 Joachim Pileborg 所说,这是一个冲洗输出问题。 只需使用以下内容:

int main()
{
    if(Fork()==0)
    {
        printf("a\n");
    }
    else
    {
        printf("b\n");
        waitpid(-1,NULL,0);
    }
    printf("c\n");
    exit(0);
}

'\n' 字符应自动刷新标准输出或标准错误。 你也可以使用 fflush(stdout);

【讨论】:

  • 我倾向于不同意,这不可能是缓冲问题,因为 exit() 将隐式刷新标准输出。
  • @Ctx 是否完全确定只有在刷新标准输出后才能唤醒父级?
  • 是的,通过标准缓冲,您将总是使用 OP 的代码获得 acbc。假设没有缓冲,另外abccbacc 是可能的。 bcac 从来没有。
猜你喜欢
  • 1970-01-01
  • 2018-07-17
  • 2016-02-22
  • 1970-01-01
  • 1970-01-01
  • 2021-07-13
相关资源
最近更新 更多