gpt4 book ai didi

c - fork函数在C中的位置及其对输出的影响

转载 作者:行者123 更新时间:2023-11-30 18:21:54 25 4
gpt4 key购买 nike

我正在学习C语言中的fork函数,并且正在准备过去的考试,遇到一个很有趣的问题。

请参阅下面的代码:

int main(void) {

printf("Hello ");
fork();
printf("Hello ");
fork();
printf("Hello \n");

pause();
return 0;
}

输出结果为

Hello Hello Hello 
Hello Hello Hello
Hello Hello Hello
Hello Hello Hello

如果我将代码更改为

    fork();
fork();
printf("Hello ");
printf("Hello ");
printf("Hello \n");

输出结果还是一样。 为什么 fork 函数的位置对输出本身没有影响。 fork 是否会等待所有 printf() 完成后再执行?这应该可以解释输出,因为第一次 printf() 会打印出 Hello 的第一行,然后它将被 fork ,并且会再打印 1 行 Hello。然后第二个 fork 将 fork 前 2 行并产生另外 2 行 Hello。

但是,问题只是稍微改变了代码,整个输出就会发生巨大变化。

printf("Hello \n");
fork();
printf("Hello ");
fork();
printf("Hello \n");

这导致输出为

Hello 
Hello Hello
Hello Hello
Hello Hello
Hello Hello

我不明白为什么只添加一个 '\n' 就会导致 5 行输出而不是 4 行。 这次,如果我像以前一样将 fork 函数的位置更改为顶部,则输出会发生变化 看来这次fork函数对printf的第一行没有影响。有人可以向我解释一下 fork 函数到底是如何输出内容的吗?

最佳答案

问题不在于顺序,这无关紧要,因为我们正在处理 fork() 并且您无法保证两个并发线程的并发性。

问题是程序打印了大量的Hello,根据程序的语义,这是不正确的。如果你仔细想想

  • 第一个 printf 仅由父进程执行
  • 第二个printf由父进程和子进程执行
  • 第三个 printf 由父进程、子进程以及父进程和第一个子进程的两个子进程执行

这总共产生了 7 个 printf,而您获得了 12 或 11 个。问题在于,当您使用以下命令调用 fork() 时,输出是按行缓冲的: stdout 缓冲区内有一些东西,然后奇怪的事情发生了。如果您将代码更改为:

#include <unistd.h>

int main(void) {
printf("(1:%u)\n", getpid());
fork();
printf("(2:%u)\n", getpid());
fork();
printf("(3:%u)\n", getpid());
pause();
return 0;
}

您将获得:

cuboid:Dev jack$ ./a.out 
(1:4307)
(2:4307)
(3:4307)
(2:4308)
(3:4309)
(3:4308)
(3:4310)

这是正确的,因为现在我们在每次调用 printf 时强制刷新(使用 \n),并且 pid 对应于我们之前看到的内容:1 、 2、4 次调用。

如果在代码中调用 fork() 之前强制刷新,例如:

int main(void) {
printf("1Hello ");
fflush(stdout);
fork();
printf("2Hello ");
fflush(stdout);
fork();
printf("3Hello \n");
pause();
return 0;
}

您将获得:

cuboid:Dev jack$ ./a.out 
1Hello 2Hello 3Hello
2Hello 3Hello
3Hello
3Hello

这会产生相同的正确结果,您可以看到父进程遍历所有 3 行,第一个子进程仅遍历第二行和第三行,而最后两个子进程仅遍历最后一行。

关于c - fork函数在C中的位置及其对输出的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34027414/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com