Search code examples
c++visual-studio-codefork

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


I try to learn the function fork(). However, the results performed using Code Runner in VScode are different from the results performed in a shell. Just like blew pictures show, I used same commands but get different results. I know that the second output in shell is right and I would like to know why is the first output printed by using Code Runner? Is something wrong about the plugin?

The code is like this.

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

enter image description here

enter image description here


Solution

  • It's a buffering issue.

    When stdout is connected to an actual terminal it will be line buffered That means the output is actually written to the terminal when the buffer is full, is explicitly flushed, or when you print a newline ('\n').

    This is what happens in the second case.

    In the first case, VSCode will not run it directly in a terminal, instead stdout will be connected to a pipe which VSCode will then output in its "terminal". When connected to a pipe (or anything else that isn't a direct terminal) then stdout will be fully buffered, where the output is flushed only when the buffer is full or explicitly flushed.

    In this first case the buffer for stdout will be inherited by the child processes, so each child-process you fork will have its own copy of the existing buffer. And when each of the child-processes exits, their buffer will be flushed and actually written. Since there are a total of eight processes running, you will get the output eight times.


    From your program to the actual output there might be multiple buffers. But the buffer I'm talking about above is the high-level stdout buffer only.

    When output to stdout is to an actual command-line environment then output will be written on newline. Otherwise the output will be buffered until the buffer is full (or explicitly flushed with fflush(stdout)).

    When running in an IDE of some kind, the output pane or window is usually a GUI control of the IDE itself, it's not a command-line environment. Therefore all output written on stdout will be stored in the stdout buffer until it's full, and then the IDE will receive it so it can write it to the output pane or window.

    Since the stdout buffer is not flushed, when you do fork() the new child process, being an almost exact copy of the parent process, will start with a stdout buffer that already have data in it.

    When the child process exits then the stdout buffer will be flushed and output written to the layers below, and the IDE will receive it to print. Since you have multiple child (and grandchild) processes, in addition to the original parent process, you will get output from each of the processes.