Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding of Fork in C [duplicate]

Tags:

c

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 .

like image 468
user3234925 Avatar asked Jan 25 '14 11:01

user3234925


People also ask

Does fork duplicate variable?

all kind of data pointers, memory, variable will be duplicate in a separate memory for the child process created with fork.

What does fork () mean in C?

In the computing field, fork() is the primary method of process creation on Unix-like operating systems. This function creates a new copy called the child out of the original process, that is called the parent.

Does fork () duplicate only the calling thread or all threads?

The fork subroutine duplicates the parent process, but duplicates only the calling thread; the child process is a single-threaded process. The calling thread of the parent process becomes the initial thread of the child process; it may not be the initial thread of the parent process.

Does fork duplicate heap?

What fork() does is the following: It creates a new process which is a copy of the calling process. That means that it copies the caller's memory (code, globals, heap and stack), registers, and open files.


2 Answers

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.

like image 59
user253751 Avatar answered Oct 15 '22 18:10

user253751


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
like image 36
kuroi neko Avatar answered Oct 15 '22 20:10

kuroi neko