Linux fork small Solution

Source: Internet
Author: User

Http://www.boluor.com/summary-of-fork-in-linux.html

The fork function is very important in Linux, because most processes are created through it. For example, when a Linux system starts, process 0 is created first, and many subsequent processes are created using do_fork. in the past two days, I learned about fork while watching the anonymous pipeline. After all, it is widely used. Here I just want to talk about it.
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, etc. 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. context consists of three parts: user-level context, register context and system-level context. the user-level context includes the body, Data, user stack, and shared storage area. The register context contains a very important program counter (legendary) PC, as well as the stack pointer and General registers; the system-level context is divided into static and dynamic parts. The input table items in the PCB, the U area, the table items in the current process, the page table, and the system area table items are all static parts, the core stack is dynamic.

Return to fork. fork corresponds to the do_fork function in the kernel. I wanted to write a description of the function myself and found that the function already exists. for details, see kernel do_fork function source code analysis. 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, the system will check whether there are any available resources, take an idle progress table item and a unique PID Number. (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 re-applies to the page and copies all of the parent process. 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 data is modified, a new page is requested, 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. since fork copies the PC, it will not be re-executed from the main entry in the sub-process, but the next command after fork is executed. 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-> mainbegin ()
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 "Hello world" is put into the buffer zone. if we add '\ n', the buffer will be refreshed, and the output will be 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 the result after the printf statement is executed. if you use setbuf settings or call fflush (0) after the printf statement; 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, which is still very different from fork. 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.