Since a function in C returns only one value, all the time, how can fork()
, which is also a function, return two values?
If you read, build, and run the following program you should get a better idea of what is going on.
#include <stdio.h>
#include <unistd.h>
int main(void) {
pid_t fk;
printf("\tbefore fork my pid = %lu\n", (unsigned long)getpid() );
fflush(stdout); /* This may keep the above print
statement from outputing twice. */
fk = fork(); /* The OS kernel makes a copy of the current process here */
printf("fork returned %lu and now my pid = %lu\n",
(unsigned long)fk, (unsigned long)getpid() );
return 0;
}
The reason that the fflush(stdout)
is needed is that since the process is duplicated by fork that means that the buffering done for stdout by stdio is duplicated as well. The "\n" at the end of that first print statement may make it go ahead and flush stdout, but this isn't guaranteed.
As Gnostus says, the fork() function does not return two values.
What it does is return a single value, the way all functions do, but it returns twice.
Once within the parent process and once within the child. The parent process gets the child's process ID returned to it, the child gets 0 - an invalid process ID, so the code can tell it is the child.
The child is a new process, running the same code and is at the same place in the code as the parent that spawned it.
int cProcessID;
cProcessID = fork();
if (cProcessID == 0) {
// Child process
} else {
// Parent process
}
The key insight here is to think about the fact that after a fork()
you have really two copies of your program. These are two processes, running the same exact copy of your code, and the execution pointer is exactly at the same line of code i.e. fork()
, poised to return.
The OS arranges for the fork()
to return in the parent process with the pid of the child, and for it to return in the child process with zero (if things go well).
That is why they say that fork()
returns twice. Once in each process.
fork
does not return two values. Right after a fork
system call you simply have two independent processes executing the same code, and the returned pid from fork
is the only way to distinguish which process are you in - the parent or the child.
The fork function returns 0 to the child process that was created and returns the childs ID to the parent process.
The two seperate processes are each returned a single value.
So think of it more as one return being called on each thread process.