为什么在 VScode 中使用 Code Runner 执行的结果与在 shell 中执行的结果不同?

Why are the results performed using Code Runner in VScode different from the results performed in a shell?

我尝试学习函数fork()。但是,在 VScode 中使用 Code Runner 执行的结果与在 shell 中执行的结果不同。就像爆炸图片显示的那样,我使用了相同的命令但得到了不同的结果。 我知道 shell 中的第二个输出是正确的,我想知道为什么使用 Code Runner 打印第一个输出?插件有问题吗?

代码是这样的

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
     printf("Hello World\n");
     fork();
     fork();
     fork();
     exit(0);
}

这是一个缓冲问题。

stdout 连接到实际终端时,它将被 行缓冲 这意味着当缓冲区已满时,输出实际上写入终端,是明确的刷新,或打印换行符时 ('\n')。

这是第二种情况。

在第一种情况下,VSCode 不会 运行 直接在终端中,而是 stdout 将连接到 管道 VSCode 然后将在其“终端”中输出。当连接到管道(或任何其他不是直接终端的东西)时,stdout 将被 完全 缓冲,只有当缓冲区已满或显式刷新。

在第一种情况下,stdout 的缓冲区将由子进程继承,因此每个 child-process 您 fork 将拥有自己的现有缓冲区副本。当每个 child-processes 退出时,它们的缓冲区将被刷新并实际写入。由于总共有八个进程运行ning,所以你会得到八次输出。


从您的程序到实际输出可能有多个缓冲区。但是我上面说的缓冲区只是 high-level stdout 缓冲区。

stdout 的输出是实际的 command-line 环境时,输出将写在换行符上。否则,输出将被缓冲直到缓冲区已满(或使用 fflush(stdout) 显式刷新)。

当 运行 在某种 IDE 中运行时,输出窗格或 window 通常是 IDE 本身的 GUI 控件,它不是 command-line环境。因此,所有写在 stdout 上的输出都将存储在 stdout 缓冲区中,直到它已满,然后 IDE 将接收它,以便将其写入输出窗格或 window.

由于 stdout 缓冲区未刷新,当您执行 fork() 时,新的子进程几乎是父进程的副本,将从 stdout 缓冲区开始里面已经有数据了。

当子进程退出时,stdout 缓冲区将被刷新并将输出写入下面的层,IDE 将接收它并打印。由于您有多个子(和孙)进程,除了原始父进程之外,您还将获得每个进程的输出。