I'm really new to C programming, although I have done quite a bit of other types of programming.
I was wondering if someone could explain to me why this program outputs 10.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
int value = 10;
int main()
{
pid_t pid;
pid = fork();
if(pid == 0){
value += 10;
}
else if(pid > 0){
wait(NULL);
printf("parent: value = %d\n", value); //Line A
exit(0);
}
}
I know the output is "parent: value = 10". Anyone know why?
Thanks!
About fork() :
- If fork() returns a negative value,
the creation of a child process was
unsuccessful.
- If fork() returns a zero to the newly
created child process.
- If fork() returns a positive value, the
process ID of the child process, to
the parent.
So in you case it bound to return a number greater than 0 & thus the value will remain 10 & will be printed.
fork
creates two processes (the "parent" and the "child"). Each process has a different value of pid in your example. The child process has a pid of 0. The parent process has a pid of the child's operating system pid (assigned by the OS.)
In your example, each process has it's own value
in its memory. They do not share memory (like you think they should by your question.) If you change one process (the first part of the if) it will not be reflected in the second process (the second part of the if.)
Edit: Explained the value of pid.
Well, fork
spawns a new process. It more or less copies the current process, and both the new one (the child) and the old one (the parent) go on at the same point in the code. But there is one significant difference (that interests us) here: for the child, fork
returns 0. For the parent, it returns the process ID of the child.
So the if(pid ==0)
part is true for the child. The child simple add 10 to his value
, and then exits since there is no further code.
The else
part is true for the parent (except for the very rare case that fork
returned an error with -1). The parent simply wait
s for the child to exit. But the child has modified its own copy of value
, the one of the parent is still untouched and that is why you get the output of "10". Then the parent also exits.
fork()
creates a new process: it has two return values in two different contexts, so both paths run in your if statement. The conditional is mostly used to determine which process you run in after the fork.
when you call fork
, it creates a copy of the process in such a way that both the copies' program counter
s are at the same position in their code sections. Hence when any of these copies resumes execution, both will just be finishing the call to fork
.
So both of them should execute identically.
BUT, fork
returns 0
in the child process, and the pid
of the child process in the parent process.
That explains the mojo behind the if( pid==0 )
part.
So when the child process changes the value of value
, it actually changes that in its own copy (remember: the process got copied, so the data sections got copied too).
Meanwhile, the parent process executes with its old value of value
, which is 10.
Even after the child changes its copy of value
and dies, the parent's copy is still 10.
The fork system call creates a new process as a child of the existing (parent) process. Both the parent and the child continue execution at the line following the fork statement, however the child process is given an exact copy of the parents address space.
The fork system call returns the process id of the newly created process to the parent and zero to the child, therefore within this code the child will increment its own copy of the value variable and the parent will print out its own copy.
You will often see fork followed by an exec within the child so that it replaces itself with another program.