Now I have a problem in understanding the working of fork()
system call.
I write a code which is following :
#include<stdio.h>
int main()
{
int a, b;
b=fork();
printf("\n the value of b = %d",b);
}
The output of this code is following :
Now I don't understand why the output is like this ?
After that i just add a line to my code and output is completely different. my code is following:
int main()
{
int a, b;
b=fork();
When i run the code the output is following 2389my name is manish
the value of b = 0
Now I'm totally confused about the working of fork()
call.
My question are following:
fork()
works?fork()
call?b
occurring at different places means in first code
the output of b = 2260
is just before the output b = 0
while the value of b = 2389
is not just before the b = 0
?Please explain me the working of fork in the code written in the problem so that I can learn it properly .
It might help to first understand why the word fork was used to name this function. Ever heard of a "fork on the road?" At a fork, the process has to split paths.
First there is a single process executing normally until you reach the fork
call. When fork is called, a new process is created, which is identical in virtually every way as the original process, except for the return value of the fork function. The newly created process is called the child process, and hence the process that spawned it is referred to as the parent process.
Since you'd want to perform different tasks for each branch of the fork, it necessitates that you be able to distinguish the child process from the parent process. That's where the return value of fork
comes in: fork
returns the process id (pid) of the child (the newly created process) to the parent; it returns 0 to the child. Also, should the execution of fork
go wrong, the return value is -1.
In your code, you don't distinguish between the child and parent process, so both processes run the entire code that follows after the fork
call.
//what the child process looks like after fork is called
int main()
{
int a, b;
b=fork(); // <-- current line of execution: 0 is returned to b
printf("\nmy name is manish\n");
printf("\n my name is anil\n");
printf("\n the value of b = %d",b);
}
// what the parent process looks like after fork is called
int main()
{
int a, b;
b=fork(); // <-- current line: child process id is returned
printf("\nmy name is manish\n");
printf("\n my name is anil\n");
printf("\n the value of b = %d",b);
}
As you can see, both processes have the same code following the fork, hence the output is repeated. Perhaps if you want the parent process to output Manish and the child to output Anil, then you can do something like:
int main()
{
pid_t b; // note that the actual return type of fork is
// pid_t, though it's probably just an int typedef'd or macro'd
b = fork();
if (b == -1) perror("Fork failed");
else if (b > 0) {
printf("My name is Manish\n"); // parent process
else
printf("My name is Anil\n"); // child process
printf("The value of b is %d\n", b);
return 0;
}
Finally, the last comment that must be made is that in your code, the output appears to have been executed first by one process in its entirety and then the other process in its entirety. That may not always be the case. For example, the operating system might allow the parent to execute the 'manish' output, then make this process wait, and handing the cpu over to the child process, which then executes 'manish'. However, the child process may continue and execute 'anil' and 'b' outputs, completing execution of the child process and thus returning execution back to the parent process. Now the parent finishes its execution by outputting 'anil' and 'b' itself. The final output of running this program may look something like:
my name is manish // executed by parent my name is anil // child the value of b = 0 // child my name is anil // parent the value of b = 2244 // parent manish.yadav@ws40-man-lin:~$
Take a look at the man page for fork
.
Also look at waitpid
for proper handling of child processes by parent processes so you don't create zombies.
Edit: In response to your questions in the comments, I'll answer how you can simply run each process consecutively.
int main()
{
pid_t pid;
int i;
for (i=0; i<NUM_PROCESSES; i++)
{
pid = fork();
if (pid == -1)
{
perror("Error forking");
return -1;
}
else if (pid > 0)
{
// parent process
waitpid(-1, NULL, 0); //might want to look at man page for this
// it will wait until the child process is done
}
else
{
// do whatever each process needs to do;
// then exit()
doProcess(i);
exit(0);
}
}
// do anything else the parent process needs to do
return 0;
}
Of course, isn't the best code, but it's just to illustrate the point. The big idea here is the waitpid
call, which causes the parent process to wait until the child process it just fork
ed to terminate. After the child prcoess completes, the parent continues after the waitpid
call, starting another iteration of the for
loop and forking another (the next) process. This continues until all child process have executed sequentially and execution finally returns to the parent.