fork(), parent and child processes???

Hi friends,
I have a small question regarding unix system call fork, I hope you will solve my problem. Here is the small program

 
$ cat fork1.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
int pid;
int x = 0;
x = x + 1;
pid = fork();
if(pid < 0)
{
printf("Fork failed\n");
return -1;
}
if(pid == 0)
printf("I am the child, my x is %d and my PID is %d\n",x,getpid());
else
printf("I am the parent, my x is %d and my PID is %d\n",x,getpid());
return 0;
}

And here is the output

$ ./fork1.exe
I am the child, my x is 1 and my PID is 1282
I am the parent, my x is 1 and my PID is 1281

Ok, when we call fork(), the following things happen

  1. The parent process passes it's memory image, including the variables
pid

and

x

, to the child process that is created.
2. fork returns zero to the child, and the child's PID, a positive integer, to the parent.
3. If fork returns a negative value, it means there was some error, and no process was created.
Ok, I am going all right till now, here comes the question that has been bothering me.
How can the single variable

pid

contain two values at the same time? zero for the child process and a positive integer for the parent process? We have two values saved in the same memory location identified by

pid

, how does that make sense. Why the values are not overwritten???
I hope you guys will help me with this mystery thing, and explain it to me.
Thanks a lot, looking forward to your nice replies!

The child is an exact* copy of the parent. Thus the child references a different chunk of memory for it's stack than the parent, and thus there are two sets of variables.

  • "exact" with a few exceptions that come into play if you are doing more than just experimenting with the fork() mechanism. See the man page for fork() to find out what isn't copied.

The address of, say, 0xbfffffffff can hold its own, separate value in each and every individual process. That's really the point of having processes -- each one gets its own flat memory space, as if it was the only thing running on the computer, but it's actually quite secure and controlled.

This virtual memory space works by dividing real memory into 4096-byte chunks, and keeping a big table of which process gets what real memory at what virtual address. This table is checked in hardware by the processor itself, and configured by the kernel. If a process tries to access a memory location where no real pages have been assigned to it, you get the familiar error "segmentation fault".

What fork() does is it makes an exact copy of the process at the time of the fork(), but gives it its own independent memory space, then twiddles the value of 'pid' so it's different in the child. It uses some tricks like copy-on-write to avoid duplicating too much memory, but that's mostly safe to ignore.

2 Likes