
非科班出身,操作系统小白。在看 Operating Systems: Three Easy Pieces 这本书。
里面有一段代码如下:

看书里的结果以及 fork()系统调用的概念,应该只会输出一遍 hello world,而我自己跑的却运行了两次
我是在 win10 的 wsl debain 上跑的。不知道是否和运行在 windows 上的 wsl 有关?还是什么其他原因?

有点神奇,上图是 WSL,下图是在另一台服务器上跑的 怀疑是 WSL 的问题。
使用的编辑器是VScode
1 lcdtyph Aug 23, 2021 via iPhone 因为你用的是 c 语言,编译器自动把初始化移动到函数最开始了。你可以把 rc 的定义和初始化分开再试试: int rc; printf(); rc = fork(); |
2 paranoiddemon OP @lcdtyph 按照这种写法,似乎还是输出了两次 |
3 hwenwur Aug 23, 2021 用 `gcc -O0 -o p1 p1.c` 编译试试 |
4 rshun Aug 23, 2021 书上是对的,估计的确是和 WSL 有关系,你换到 Linux 环境试试 |
5 QHKZ Aug 23, 2021 ubuntu 虚拟机与书上的一致,估计是 wsl 的问题。 |
6 ysc3839 Aug 23, 2021 via Android 我比较怀疑第一次 printf 的数据存在缓冲区内没有真正输出,fork 后才输出所以会有两个。 |
7 liuguangxuan Aug 23, 2021 via Android printf 为行缓冲,fork 的时候如果还没有 flush 的话,fork 之后父子进程各保留一份。所以会显示输出两份。《 Unix 环境高级编程》书上有讲。 |
8 GeruzoniAnsasu Aug 24, 2021 @liuguangxuan @ysc3839 行缓冲只会把换行前的东西缓冲,遇到\n 会 flush 的 我在 wsl 里也没复现,不知道是什么神奇的现象 要么 wsl debian 比较奇怪,要么 vscode 比较奇怪,我是没搞懂 |
9 xarthur Aug 24, 2021 看起来没什么奇怪的地方,倾向是 WSL Windows 的问题。 |
10 liuguangxuan Aug 24, 2021 via Android @GeruzoniAnsasu 难道是遇到了\n 没有 flush ? @paranoiddemon 可以手动调用一下 fflush 验证一下,或者 setvbuf 设置为不缓冲。 |
11 paranoiddemon OP   有点神奇,上图是 WSL,下图是在另一台服务器上跑的 怀疑是 WSL 的问题。 |
12 AoEiuV020 Aug 24, 2021 第一反应也是缓冲问题,看截图像是 vscode,这种第三方的终端甚至未必和普通终端有一样的缓冲处理, |
13 infreboot Aug 24, 2021 vagrant init bento/ubuntu-20.04 vagrant up 解君愁 |
14 misaka19000 Aug 24, 2021 搞个 Linux 虚拟机,别在 Windows 下面玩这些 |
15 paranoiddemon OP |
16 crystom Aug 24, 2021 我也复现了,用的 code runner,跟你一样的情况。不过我把下面两个打印去掉也会有这个情况,猜测是 code runner 的问题。直接在终端或者 vscode 终端运行不会出问题 |
17 crystom Aug 24, 2021 搜索了一下,早在去年就有人提出了类似的问题,https://github.com/formulahendry/vscode-code-runner/issues/579 |
18 paranoiddemon OP @crystom 谢谢,应该就是这个的原因,我也使用了 code runner 。在 vscode 终端没有问题。但是又发现个奇怪的问题,windows terminal 里也会出现这种问题,但是直接打开 debian 的终端就不会。 |
19 2i2Re2PLMaDnghL Aug 25, 2021 话说进了 FIFO 的内容如果还没被消费掉就 fork 会不会一起被复制? |