Why there are many PIDs printed while using fork s

2019-07-19 22:16发布

问题:

I am learning the process management in Linux and I tried implementing the following C program, the output of which printed 15 PIDs(4 unique PIDs). I tried to figure out the process family tree but it really didnt help me understand why the PIDs were printed so many times. I went through few links including http://u.cs.biu.ac.il/~linraz/os/OS2.pdf, http://www.ibm.com/developerworks/aix/library/au-unixprocess.html , Who executes first after fork(): parent or the child? . But, I couldn't find the solution. It would be of great help if somebody helps me to understand this problem.

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

    int main()
    {
           printf ( "Parent:%d Child: %d\n",getppid(),getpid()); // To print the PIDs of the parent process and the child process
           fork();               //System call to spawn a child process
           printf ( "Parent:%d Child: %d\n",getppid(),getpid()); 
           fork();
           printf ( "Parent:%d Child: %d\n",getppid(),getpid());
           fork();
           printf ( "Parent:%d Child: %d\n",getppid(),getpid());
           return 0;
    }

回答1:

When your program is launched, the kernel assigns it a PID. The PPID, is the PID of the process that launched the program, usually your shell. For the purposes of this answer, we'll assign your shell the PID of 123, and your program, at start, will be assigned the pid of 130.

The first line of output will simply display the PPID and the PID.

Parent:123 Child: 130

The next thing the program does is split itself in two. The original program's PID and PPID are unchanged, the child's PPID is the original program's PID, and the child is assigned a new PID. As both programs are still tied to the same output channel, either one's output could be displayed first. For simplicity, we'll pretend output is ordered.

Parent:123 Child: 130
Parent:130 Child: 131

Now you're forking a second time... both process duplicate themselves. You now have four processes that want to print output to the same channel.

Parent:123 Child: 130
Parent:130 Child: 131
Parent:130 Child: 132
Parent:131 Child: 133

Now, with your third fork, all four of these processes duplicate themselves again.

Parent:123 Child: 130
Parent:130 Child: 131
Parent:130 Child: 132
Parent:131 Child: 133
Parent:130 Child: 134
Parent:131 Child: 135
Parent:132 Child: 136
Parent:133 Child: 137

Any questions?



回答2:

fork() creates a new process by duplicating the calling process. The new process, referred to as the child, is an exact duplicate of the calling process, referred to as the parent.

A fork() 
|----------------B
|                |   
|fork()          |
|----C           |
|    |           |

When ever if you made call to fork() the next instructions will be executed by child process and parent parent process

Your program look like this

       printf ("Hi"); //prints only one time   
       fork();
       printf ("Hi"); //prints two times
       fork();
       printf ("Hi"); //prints four times 

consider all fork() created child process successfully.

       printf ("Hi"); 
       fork();------------------------------------------------|
          |                                                   | 
       printf ("Hi");                                       printf ("Hi"); 
       fork();----------------|                             fork();---------------|
       printf ("Hi");      printf ("Hi");                   printf ("Hi");        printf ("Hi"); 


回答3:

Each time you call fork you're duplicating the current process. So the first printf is executed once- there's only one process. You then call fork() so the second printf is executed twice- once on the parent process and once on the new child process. Then the parent and child each fork creating 4 process total, etc...



回答4:

When you fork, a new process is created, but the parent continues its execution too. So your main will execute all 4 prints, your first fork will execute the subsequent 3 prints and so on. To have control on what code each child and parent will execute, you will have to use the fork return value, not just fork.