A good foreign company interviewed the Linux development position, the interviewer had a following question:
Give the following C program, compile with gcc under Linux:
It is known that all processes executing from this program to this program end within this time period, and no other new processes are executed.
Please say that after executing this program, several processes will be run in total.
If the output of one of the processes is "pid1:1001, pid2:1002", write the output of other processes (regardless of the order in which the processes are executed).
Obviously the purpose of this question is to examine the execution mechanism of fork under linux. Below we analyze this topic and talk about the operating mechanism of fork under Linux.
Prerequisite knowledge:
Here are some of the necessary preliminary knowledge, and friends who are familiar with the process mechanism under Linux can skip it.
A process can be seen as an execution of a program. Under Linux, each process has a unique PID identity process. The PID is a positive integer from 1 to 32768, where 1 is usually a special process init, and other processes are numbered sequentially from 2. When you run out of 32768, start over from 2.
Linux has a structure called a process table to store the currently running process. You can use the "ps aux" command to view all running processes.
The process is a tree structure in Linux, init is the root node, and other processes have parent processes. The parent process of a process is the process that starts the process. This process is called the child process of the parent process.
The role of fork is to copy a process that is the same as the current process. All data (variables, environment variables, program counters, etc.) of the new process are the same as the original process, but are a completely new process and act as a child of the original process.
The key to solving the problem:
With the above preparatory knowledge, let's take a look at the key to solving the problem. I think the key to solving the problem is to realize that fork cuts the program into two paragraphs. Look at the picture below:
The above figure shows a program with a fork, and the fork statement can be seen as cutting the program into two parts, A and B. Then the entire program will run as follows:
Step1, the program is executed directly by the shell, and the process P is generated. P executes all the code of Part. A.
Step2, when executing to pid = fork();, P starts a process Q, Q is a child process of P, and P is the process of the same program. Q inherits all variables of P, environment variables, and the current value of the program counter.
Step3. In the P process, fork() returns the PID of Q to the variable pid and continues to execute the code of Part.B.
Step4, in process Q, assign 0 to pid and continue to execute Part. B code.
There are three points that are critical here:
P executes all the programs, and Q only executes Part. B, which is the program behind fork(). (This is because Q inherits P's PC-program counter)
Q inherits the current environment when the fork() statement is executed, not the initial environment of the program.
The fork() statement in P starts the child process Q and returns the PID of Q, while the fork() statement in Q does not start the new process, only 0 is returned.
Problem solving:
The following uses the knowledge set forth above to solve the problem. Here I put the two questions together for analysis.
Execute this program from the shell, start a process, we set this process to P0, set its PID to XXX (the problem process does not need to know its PID).
When executing to pid1 = fork();, P0 starts a child process P1, and the PID of the P1 is 1001. We will not care about P1 for the time being.
The fork in P0 returns 1001 to pid1, and continues to pid2 = fork(); at this point, another new process is started, set to P2, and the PID of the P2 is 1002. Also for the time being, regardless of P2.
The second fork in P0 returns 1002 to pid2, continues to execute the subsequent program, and ends. Therefore, the result of P0 is "pid1:1001, pid2:1002".
Look at P2. When P2 is generated, pid1=1001 in P0, so pid1 in P2 inherits 1001 of P0, and as subprocess pid2=0. P2 starts execution after the second fork, and outputs "pid1:1001, pid2:0" after the end.
Then look at P1, the first fork in P1 returns 0 to pid1, and then executes the following statement. The next statement is pid2 = fork(); execution here, P1 has a new process, set to P3. Regardless of P3.
The second fork in P1 returns the PID of P3 to pid2. From the preliminary knowledge, the PID of P3 is 1003, so the pid2 of P1 is=1003. P1 continues to execute the subsequent program, and ends, outputting "pid1:0, pid2:1003".
P3 is a subprocess of P1, inherits pid1=0 in P1, and the second fork returns 0 to pid2, so P3 finally outputs "pid1:0, pid2:0".
At this point, the entire implementation process is completed.
The answer is:
1. A total of four processes were implemented.
(P0, P1, P2, P3)
2. The output of several other processes are:
Pid1:1001, pid2:0 pid1:0, pid2:1003 pid1:0, pid2:0
Further, a process tree rooted at P0 can be given:
verification:
Below we go to linux to actually execute this program to verify our answer.
The program is as follows:
After compiling and executing with gcc, the results are as follows:
Since it is unlikely that we happen to run into the case where the PID is assigned to 1001, the exact value may differ from the answer. However, if 2710 is used as the base, the result is consistent with our answer above.
to sum up:
It should be said that this is not a particularly difficult or particularly problematic topic, but due to the complexity of the fork function running mechanism, the problem becomes complicated when the two forks are side by side. The key to solving this problem is to have a certain understanding of the mechanism of the Linux process, and the second is to grasp the key points of the fork mentioned above. The friend said that the time given for this question is 5 minutes. It should be said that the time is still sufficient, but in the interview situation, it is still a test of a person's mastery of the process, fork and on-the-spot reasoning ability.
Ningbo Autrends International Trade Co.,Ltd. , https://www.supervapebar.com