Fork summary in Linux

Source: Internet
Author: User

The fork function is very important in Linux, because most of the processes are created through it. For example, when a Linux system starts, the process 0 is created first, and many subsequent processes obtain
In the past two days, I learned about fork while viewing anonymous pipelines. After all, fork has a wide range of applications. Here I will only talk about what I have learned.
First, let's take a look at Example 1.

#include "stdio.h" 
#include "unistd.h"
#include "stdlib.h"
 
int main(){
int i;
printf("hello world %d/n",getpid());
i=3;
fork();
printf("var %d in %d/n",i,getpid());
return 0;
}

What is output?
This is the result of the last execution on my machine:

Hello World 8168
VaR 3 in 8169
VaR 3 in 8168

Why does one output three rows of VaR twice? It seems incredible... To explain the reason, it involves the fork we want to discuss. What has it actually done?

Fork indicates a cross. the process is split from here into two processes. One is the parent process and the other is the child process. the child process copies the vast majority of the parent process. stack, buffer zone
And so on. the system creates a new process entry for the child process, where the process ID is different from the parent process, which means that the parent and child processes are two independent processes, although the Parent and Child processes share the code space. however
When writing data, the child process has its own data space. This is because of the copy on write mechanism. When there is data modification, the system will apply for a new page for the child process.

Next, let's review the related process knowledge. the system manages processes through process control block PCB. the execution of a process can be considered to be executed in its context. the context of a process consists of three
Sub-structure: user-level context, register context and system-level context. user-level context includes body, Data, user stack, and shared storage area. register context contains a very important program counter (in the legend
) PC, as well as the stack pointer and General registers; the system-level context is divided into static and dynamic, the progress table items in the PCB, the U area, and the table items in the process, the page table, system Partition Table items all belong to the static part, and the core
Stack is a dynamic part.

Back to fork. Fork corresponds to the do_fork function in the kernel. I wanted to write down the function description and found that the function already exists. For details, see: Kernel
Source code analysis of do_fork Functions
.
As mentioned above, after fork, the child process copies the progress table of the parent process, as well as stack a, buffer zone, u zone, and so on. before that, of course, we will check whether the system has any available resources and take an idle table.
And a unique PID. (The following example shows what the child process copied to the parent process .) it should be noted that the copy mentioned here does not mean that the sub-process applies to the page again
All in. instead, they share a space, and the child process only performs a layer of ing. In this case, the process page is marked as read-only. when there is data modification, a new page will be applied, copied, and marked
As writable.

After fork is executed, the difference between the parent process and the child process is that the PID Number of the child process returned by the parent process is 0. The approximate algorithm is described as follows:

If (the parent process is currently being executed ){
Set the sub-process status to "ready ";
Return (pid of the sub-process );
} Else {/* sub-processes in progress */
Initialize the U zone;
Return 0;
}

Now let's look at Example 1. Is it much clearer?
After fork is executed, both parent and child processes execute the next printf statement. Because fork copies the PC, it will not be re-executed from the main entry but will be executed in the child process.
The next command after fork. While I is stored in the process stack space, so sub-processes also exist.
With the previous Foundation, let's look at Example 2 below:

# Include <stdio. h>
# Include <unistd. h>
Int main ()
{
Int I = 0;
Pid_t fork_result;
Printf ("PID: % d --> main begin ()/n", getpid ());
 
Fork_result = fork ();
 
If (fork_result <0 ){
Printf ("Fork failure/N ");
Return 0;
}
For (I = 0; I <3; I ++ ){
If (fork_result = 0) {// in the sub-process.
Printf ("child process: % d/N", I );
} Else {
Printf ("Father process: % d/N", I );
}
}
Return 0;
}

This output clearly shows what the sub-process has copied. The two execution results on my machine:

Boluor @ boluor-LAPTOP :~ /Programs/pipe/fork $./A. Out
PID: 16567-> main begin ()
Child process: 0
Child process: 1
Child process: 2
Father process: 0
Father process: 1
Father process: 2
Boluor @ boluor-LAPTOP :~ /Programs/pipe/fork $./A. Out
PID: 16569-> main begin ()
Father process: 0
Father process: 1
Father process: 2
Child process: 0
Child process: 1
Child process: 2

It also shows which parent and child processes are executed first, which is related to CPU scheduling. If you want to fix the order, you need to use the wait or vfork function.
Example 3:

#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
 
int main()
{
printf("hello world %d",getpid());
//fflush(0);
fork();
return 0;
}

After executing the above program, we can find that the output is Hello world twice, and the PID numbers are the same twice. Why?
This is actually because of the row buffering problem of printf. After the printf statement is executed, the system places the string in the buffer and does not output it to stdout. If you do not understand it, refer to the following example:

#include "stdio.h"
int main(){
printf("hello world");
while(1);
return 0;
}

When you execute the above program, you will find that the program is in an endless loop and no "Hello world" is output. This is because the "hello"
World "is placed in the buffer zone. If we add '/N' normally, the buffer will be refreshed and output directly to stdout.

Because the sub-process copies the buffer, the sub-process also prints it. the parent process is not output until the end. their output is the same, and the output PID is the same, because the sub-process copies
Result of printf statement execution. If you use setbuf to set or call fflush (0) after the printf statement, and force refresh the buffer, this problem will not occur.
In this example, the child process also copies the buffer of the parent process.

There are still many fork applications, which need to be further studied in actual projects. regarding the difference between fork and exec, exec replaces the image of this process.
In fact, after fork creates a sub-process, in most cases, the sub-process will call exec to execute different programs.

Let's talk about it first. If you need more fork knowledge, Google ^. ^.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.