6

I have one problem with fork that i don't undertsand.

    #include <stdio.h>
    #include <string.h>

    main(){
      printf("test 1.\n"); 

      fork();

      printf("test 2.\n");  
    }

the output is :

test 1.
test 2.
test 1.
test 2.

Shouldn't i be getting... :
test1
test2
test2

I really don't understand this because fork should create child process after the fork(); and not printing the teste1 again .

2 Answers2

5

When you call printf, it doesn't print any text immediately. Instead it waits until you've printed a lot of text, or you call fflush(stdout), or the program exits. (Edit: There are also other things that will cause buffered text to be printed)

When the process forks, it copies the buffer of un-printed text (which contains "test 1.\n"). Both processes then print "test 1.\n" when they exit.

Calling fflush(stdout) before fork() fixes this, by making sure "test 1.\n" is actually printed before the process forks.

user253751
  • 57,427
  • 7
  • 48
  • 90
1

try this:

void exit_message (void)
{
   // use write to have an unbuffered output
   char m[100];
   sprintf (m, "%d exit\n", getpid());
   write (1, m, strlen(m));
}

main(){
  atexit (exit_message);

  printf("%d test 1\n",getpid()); 

  fork();

  printf("%d test 2\n",getpid());
  }

The output will look like this:

14866 exit   // <- parent process flushes its output at exit
14866 test 1 // <- parent process: 1st printf
14866 test 2 // <- parent process: 2nd printf
14867 exit   // <- forked process flushes its output at exit
14866 test 1 // <- forked process: unflushed parent process output buffer
14867 test 2 // <- forked process: 2nd printf

we can see the only printf done by the forked process is the last one, as expected.

The previous line is a ghost of the stdout output buffer, which has been duplicated by fork() before being flushed.

Making stdout unbuffered

main(){
  atexit (exit_message);
  setvbuf(stdout, NULL, _IONBF, 0);
  printf("%d test 1\n",getpid()); 

  fork();

  printf("%d test 2\n",getpid());
}

gets rid of the ghost

14866 test 1 // <- parent process: 1st printf
14866 test 2 // <- parent process: 2nd printf
14866 exit   // <- parent process exits
14867 test 2 // <- forked process: 2nd printf
14867 exit   // <- forked process exits
kuroi neko
  • 8,479
  • 1
  • 19
  • 43