V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
paranoiddemon
V2EX  ›  程序员

请教一个操作系统进程 fork 相关的问题

  •  
  •   paranoiddemon · 2021-08-23 22:09:14 +08:00 · 2354 次点击
    这是一个创建于 1218 天前的主题,其中的信息可能已经有所发展或是发生改变。

    非科班出身,操作系统小白。在看 Operating Systems: Three Easy Pieces 这本书。

    里面有一段代码如下:

    program result

    看书里的结果以及 fork()系统调用的概念,应该只会输出一遍 hello world,而我自己跑的却运行了两次

    我是在 win10 的 wsl debain 上跑的。不知道是否和运行在 windows 上的 wsl 有关?还是什么其他原因?

    第 1 条附言  ·  2021-08-24 09:18:46 +08:00

    wsl centos

    有点神奇,上图是 WSL,下图是在另一台服务器上跑的 怀疑是 WSL 的问题。

    使用的编辑器是VScode

    19 条回复    2021-08-25 14:57:46 +08:00
    lcdtyph
        1
    lcdtyph  
       2021-08-23 22:14:10 +08:00 via iPhone
    因为你用的是 c 语言,编译器自动把初始化移动到函数最开始了。你可以把 rc 的定义和初始化分开再试试:

    int rc;
    printf();
    rc = fork();
    paranoiddemon
        2
    paranoiddemon  
    OP
       2021-08-23 22:21:39 +08:00
    @lcdtyph 按照这种写法,似乎还是输出了两次
    hwenwur
        3
    hwenwur  
       2021-08-23 22:26:02 +08:00
    用 `gcc -O0 -o p1 p1.c` 编译试试
    rshun
        4
    rshun  
       2021-08-23 22:27:59 +08:00
    书上是对的,估计的确是和 WSL 有关系,你换到 Linux 环境试试
    QHKZ
        5
    QHKZ  
       2021-08-23 22:51:10 +08:00
    ubuntu 虚拟机与书上的一致,估计是 wsl 的问题。
    ysc3839
        6
    ysc3839  
       2021-08-23 23:31:31 +08:00 via Android
    我比较怀疑第一次 printf 的数据存在缓冲区内没有真正输出,fork 后才输出所以会有两个。
    liuguangxuan
        7
    liuguangxuan  
       2021-08-23 23:33:20 +08:00 via Android
    printf 为行缓冲,fork 的时候如果还没有 flush 的话,fork 之后父子进程各保留一份。所以会显示输出两份。《 Unix 环境高级编程》书上有讲。
    GeruzoniAnsasu
        8
    GeruzoniAnsasu  
       2021-08-24 07:26:11 +08:00
    @liuguangxuan
    @ysc3839
    行缓冲只会把换行前的东西缓冲,遇到\n 会 flush 的
    我在 wsl 里也没复现,不知道是什么神奇的现象





    要么 wsl debian 比较奇怪,要么 vscode 比较奇怪,我是没搞懂
    xarthur
        9
    xarthur  
       2021-08-24 07:55:17 +08:00
    看起来没什么奇怪的地方,倾向是 WSL Windows 的问题。
    liuguangxuan
        10
    liuguangxuan  
       2021-08-24 08:43:26 +08:00 via Android
    @GeruzoniAnsasu 难道是遇到了\n 没有 flush ? @paranoiddemon 可以手动调用一下 fflush 验证一下,或者 setvbuf 设置为不缓冲。
    paranoiddemon
        11
    paranoiddemon  
    OP
       2021-08-24 09:16:08 +08:00
    ![wsl]( https://i.bmp.ovh/imgs/2021/08/84d828524554e0b6.png)
    ![centos]( https://i.bmp.ovh/imgs/2021/08/b3a78740a32f59a2.png)

    有点神奇,上图是 WSL,下图是在另一台服务器上跑的
    怀疑是 WSL 的问题。
    AoEiuV020
        12
    AoEiuV020  
       2021-08-24 09:17:42 +08:00
    第一反应也是缓冲问题,看截图像是 vscode,这种第三方的终端甚至未必和普通终端有一样的缓冲处理,
    Stevenv
        13
    Stevenv  
       2021-08-24 09:52:30 +08:00
    vagrant init bento/ubuntu-20.04
    vagrant up

    解君愁
    misaka19000
        14
    misaka19000  
       2021-08-24 10:05:31 +08:00
    搞个 Linux 虚拟机,别在 Windows 下面玩这些
    paranoiddemon
        15
    paranoiddemon  
    OP
       2021-08-24 10:38:18 +08:00 via Android
    @Stevenv
    @misaka19000
    有个腾讯云的 Linux 主机。WSL 比较顺手所以就用 WSL 了。
    crystom
        16
    crystom  
       2021-08-24 13:46:44 +08:00
    我也复现了,用的 code runner,跟你一样的情况。不过我把下面两个打印去掉也会有这个情况,猜测是 code runner 的问题。直接在终端或者 vscode 终端运行不会出问题
    crystom
        17
    crystom  
       2021-08-24 13:49:04 +08:00   ❤️ 1
    搜索了一下,早在去年就有人提出了类似的问题,https://github.com/formulahendry/vscode-code-runner/issues/579
    paranoiddemon
        18
    paranoiddemon  
    OP
       2021-08-24 14:57:24 +08:00
    @crystom 谢谢,应该就是这个的原因,我也使用了 code runner 。在 vscode 终端没有问题。但是又发现个奇怪的问题,windows terminal 里也会出现这种问题,但是直接打开 debian 的终端就不会。
    2i2Re2PLMaDnghL
        19
    2i2Re2PLMaDnghL  
       2021-08-25 14:57:46 +08:00
    话说进了 FIFO 的内容如果还没被消费掉就 fork 会不会一起被复制?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3103 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 00:40 · PVG 08:40 · LAX 16:40 · JFK 19:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.