Home > Blockchain >  fork() start of execution
fork() start of execution

Time:11-28

I am pretty new to unix programming and came across something I do not understand. Here it is the following code snippet:

#include <stdio.h>
#include <sys/types.h>

int main()
{
     printf("%d ", fork());
     return 0;
}

The output is: 9298 0. Why does the child process call this printf ? At my course I was told that it executes everything after the fork() call. What am I getting wrong ?

CodePudding user response:

The result of fork is passed to printf so it is executed before printf. Your code is equivalent to:

#include <stdio.h>
#include <sys/types.h>

int main()
{
     pid_t pid = fork();
     printf("%d ", pid);
     return 0;
}

CodePudding user response:

When the child process starts, it starts exactly where the fork call was made, which is in the middle of a printf call.

So now both the parent and the child processes will finish their own separate printf call, each outputting its own return value.

CodePudding user response:

What you were told is inaccurate. What happens is that a fork is an (almost identical) copy of the process.

So it continues with the fork() returning the values in the parent and the child. And printf continuing in both processes.

Think of the running program creating a clone (there is irony in this explanation I'll get to in a bit ;)) of itself and the two doing the same thing from that point on wards. The only difference from a program's internal perspective is the return value that the OS gives to each of the copies. The parent receives the process id (pid) of the child program whereas the child program receives a 0. This is how they can distinguish themselves from each other easily.

Snippet from the fork manual page:

The snippet below shows more details about what are the differences between the "parent" and "child" process:

   fork() creates a new process by duplicating the calling process.
   The new process is referred to as the child process.  The calling
   process is referred to as the parent process.

   The child process and the parent process run in separate memory
   spaces.  At the time of fork() both memory spaces have the same
   content.  Memory writes, file mappings (mmap(2)), and unmappings
   (munmap(2)) performed by one of the processes do not affect the
   other.

   The child process is an exact duplicate of the parent process
   except for the following points:

   *  The child has its own unique process ID, and this PID does not
      match the ID of any existing process group (setpgid(2)) or
      session.

   *  The child's parent process ID is the same as the parent's
      process ID.

   *  The child does not inherit its parent's memory locks
      (mlock(2), mlockall(2)).

   *  Process resource utilizations (getrusage(2)) and CPU time
      counters (times(2)) are reset to zero in the child.

   *  The child's set of pending signals is initially empty
      (sigpending(2)).

   *  The child does not inherit semaphore adjustments from its
      parent (semop(2)).

   *  The child does not inherit process-associated record locks
      from its parent (fcntl(2)).  (On the other hand, it does
      inherit fcntl(2) open file description locks and flock(2)
      locks from its parent.)

   *  The child does not inherit timers from its parent
      (setitimer(2), alarm(2), timer_create(2)).

   *  The child does not inherit outstanding asynchronous I/O
      operations from its parent (aio_read(3), aio_write(3)), nor
      does it inherit any asynchronous I/O contexts from its parent
      (see io_setup(2)).

Clone in Linux

If you are using Linux, the fork() call is a wrapper (actually a subset) of clone() system call. For more information on that see:

https://man7.org/linux/man-pages/man2/clone.2.html

  • Related