1
votes

This is the C code to test fork() system call:

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<wait.h>

int main(int argc, char *argv[])
{

    printf("I am: %d\n", (int)getpid());

    pid_t pid = fork();

    printf("fork returned: %d\n", (int)pid);

    if (pid < 0)
    {
        perror("fork failed");  
    }

    if (pid==0)
    {
        printf("I am the child with pid %d\n", (int)getpid());
        sleep(5);
        printf("Child exiting...\n");
        exit(0);
    }

    printf("I am the parent with pid %d, waiting for the child\n", (int)getpid());
    wait(NULL);
    printf("Parent ending. \n");

    return 0;
}

The output in terminal is:

I am: 25110
fork returned: 25111
I am the parent with pid 25110, waiting for the child
fork returned: 0
I am the child with pid 25111
Child exiting...
Parent ending. 

Question: When fork returned: 0, it is in the child process. But the child process shows I am the child with pid 25111. I thought the child process pid should be 0, why it changes to 25111?

Same thing with the parent process, fork returned 25111, but getpid() returns 25110 (I am the parent with pid 25110, waiting for the child)

2
You need to read a lot more. Read advancedlinuxprogramming.com ; we can't explain here what needs an entire book to be explained. Notice that fork is tricky to understand, so take time! Read also many times fork(2) and fork wikipage - Basile Starynkevitch
BTW, the ONLY PID which is 0 is init - Claudio Cortese
init is pid 1. There is literally (this is a POSIX requirement) no such thing as pid 0 since 0 has special meaning to various interfaces that take or return pids -- in particular, fork. - R.. GitHub STOP HELPING ICE
@R.. That's what I thought, too, although on the first machine where I tried it (an old SunOS machine), ps shows a pid 0 called "swapper". (But, yes, init is pid 1.) - Steve Summit
@SteveSummit: It's something of a pseudo-process in the kernel's management of processes, but you can't interact with it using any functions that take pid arguments because it's not a valid pid number. Linux similarly has a "pid 0" that's the idle task (for cpu0 anyway), I think. - R.. GitHub STOP HELPING ICE

2 Answers

9
votes

the child process shows I am the child with pid 25111. I thought the child process pid should be 0

No. In the parent fork() returns the pid of the child. In the child, fork returns 0 -- which is not the pid of anything, it's just a marker. The child pid is 25111, as getpid told you.

with the parent process, fork returned 25111, but getpid() returns 25110

Right. The parent pid was always 25110, as getpid told you. And fork() returned the pid of the new child.

The fact that fork returned the same value in the parent as getpid returned in the child proves that this is all working properly.

It sounds like you think fork() always returns the pid of the process that you're in. But that wouldn't make sense -- we already have the getpid call for that.

If you're the parent, fork() returns the pid of the other process, the child. And if you're the child, fork() doesn't return a pid at all. (If you're the child and you want to know the pid of your parent, that's a good, frequent, and separate question. Answer: call getppid().)

We can summarize all this as follows:

                 parent   child
                 ------   -----
pid:              25110   25111
fork returns:     25111       0
getpid returns:   25110   25111
getppid returns:  ?????   25110

The way to remember this is to think about the code that's going to be calling fork(): what it's going to do, what it needs to know. The parent needs to know that it is the parent. The child needs to know that it is the child. The parent very often needs to know the pid of the child (and would have no other way of obtaining it).

If fork always returned a pid, then after the fork call, looking at its return value, you would have no way of knowing whether you were the parent or the child -- but this is typically the first and most important thing you need to know.

(In all of this I've ignored the third possibility, namely that fork fails, and returns -1 in the parent, and doesn't return anything in the child, because there isn't one.)

See also Why fork() return 0 in the child process? .

3
votes

fork returning 0 does not mean your pid is 0. It's simply the return value fork uses to tell you that you're the child process. In fact fork never returns your pid; it returns either:

  • the pid of your child,
  • 0, meaning you are the child, or
  • -1, indicating an error occurred (and no child process was created)