The difference between linux-fork (), Vfork () and clone __linux

Source: Internet
Author: User
Tags assert function prototype signal handler

In a Linux system, fork (), vfork () and the Clone function can all create a process, but what are their differences ... This article on these three to do a more in-depth analysis ...

1.fork ()

The fork () function is to create a new process, the process created by Fork is called a subprocess, the fork function call returns two times, the child process returns a value of 0, and the parent process returns the process ID of the child process. We know that the land of a process

The address space is mainly composed of code segment, data segment, heap and stack, then P2 should copy the related segment to the physical memory. The original UNIX system was implemented with a silly

The melon-style process is created, and these replications include:

(1) Assigning pages to the page table of the subprocess to determine the location of the page table;

(2) assigning pages to the pages of the subprocess to determine the location of the child process pages;

(3) Initialize the page table of subprocess;

(4) Copy the page of the parent process to the page corresponding to the child process

From the diagram we can see that all the other segments of the child process have physical space in addition to the body paragraph and copy the contents of the parent process. The open file descriptor in the TASK_STRUCT structure of the parent process, the process group ID,

The reply ID is replicated.

The following fork () function is detected by simple code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h >
#include <pthread.h>
#include <assert.h>
#include <iostream>
using namespace Std;

int main () {
        int num = 1;
        int child;
        if (!) ( Child =fork ()) {
		cout<<&num<<endl;
                printf ("Son process, num:%d, address:%p, PID is:%d\n", Num,&num, Getpid ());
		num++;
		cout<< "num:" <<num<<endl;
		cout<< "Address:" <<&num<<endl;
		Sleep (a);
		Exit (0);
        } else {sleep
		(1);
                printf ("Father process, num:%d, address:%p, PID is:%d\n", Num,&num, Getpid ());		
		Sleep ();		
		Exit (0);
        }
}

Virtual space for the process:

Virtual address space for child processes:


Virtual address space for the parent process:

You can see that the child process and the parent process have the same address space.

But the effect of this method is very bad, if the EXEC function cluster is called immediately after the fork process, then the original copy of the parent process's data segment, stack, and the related copy of the heap will become futile. Later, people thought of a

The alternative, which is write-time replication (Copy-on-write,cow technology), allows the parent process and child processes to share the upper zone, and the kernel converts the access rights of those segments to read-only. In the case of a parent process or a child process

Any attempt to modify these areas, the kernel makes only one copy of the memory that modifies the region, usually one of the "pages" of the virtual storage System. Here is a detailed illustration of the technique in the absence of a write operation, if Zijin

The written page needs to be copied to the physical space if any one of the threads or the parent process has a write operation;


As you can see from the diagram, the cow technology does not allocate memory space to the related segments of the child process when the process calls fork (). This approach has greatly improved the efficiency of calling EXEC function clusters after fork (). In this case, the inner

The kernel only needs to create a task_struct for the subprocess, which means that if the child process calls the EXEC function cluster to execute another executable, the core may just create a new task_struct structure and copy the contents of the parent process

, thus greatly saving the consumption of blind copy.

2.vfork ()

The Vfork () function is also used to create a new process, and the purpose of the new process is to exec a new program, and let's take a look at the simple test:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h >
#include <pthread.h>
#include <assert.h>
#include <iostream>
using namespace Std;

int main () {
        int num = 1;
        int child;
        if (!) ( Child =vfork ()) {
		cout<<&num<<endl;
                printf ("Son process, num:%d, address:%p, PID is:%d\n", Num,&num, Getpid ());
		num++;
		cout<< "num:" <<num<<endl;
		cout<< "Address:" <<&num<<endl;
		Sleep (2);
		Exit (0);
        } else {sleep
		(1);
                printf ("Father process, num:%d, address:%p, PID is:%d\n", Num,&num, Getpid ());		
		Sleep (2);		
		Exit (0);
        }
}

Test results:

From the test results, we can see that after the subprocess has modified the value of the NUM variable, the value of the NUM of the parent process also changes, indicating that for both the subprocess and the parent process, they operate in the same place as the NUM value, the following is the diagram of the vfork:

You can see that the child process shares the virtual process space of the parent process directly.

3. Clone ()

The Clone () function is a Linux system used to create lightweight processes.

Function prototype:

int clone (int (*FN) (void *), void *child_stack, int flags, void *arg);
The following is flags can take the value of the
flag                    meaning
clone_parent   created by the parent process is the caller's parent process, the new process and the process of creating it became "brothers" rather than "father and son"
clone_fs           The child process shares the same file system as the parent process, including root, current directory, Umask
clone_files,      and the parent process share the same file descriptor (Files descriptor) Table
clone_newns   in the new namespace boot Subprocess, namespace describes the process's file hierarchy
The Clone_sighand   child process shares the same signal processing (signal handler) table as the parent process
Clone_ptrace   If the parent process is trace, the subprocess is also trace
Clone_ Vfork the     parent process is suspended until the subprocess frees the virtual memory resource CLONE_VM The child process
runs in           the same memory space as the parent process
Clone_pid The          PID is consistent with the parent process at the time of creation
Clone_thread    Increased in Linux 2.4 to support POSIX threading standards, the child processes share the same line as the parent process Cheng
The following example is creating a thread (the Subprocess shares the virtual memory space of the parent process and cannot be called a process without its own virtual space). The parent process is suspended when the child thread frees the virtual
storage resource and continues execution.
Test Code 1:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h >
#include <pthread.h>
#include <assert.h>
#include <iostream>
using namespace Std;
#define FIBER_STACK 8192

int A;
void * STACK;
int func (void *) {
	cout<<&a<<endl;
        printf ("This is son, the PID is:%d, the A are:%d\n", Getpid (), ++a);
        Free (stack); 
        Exit (1);
}
int main () {
        void * stack;
        A = 1;
        stack = malloc (fiber_stack);
        if (!stack) {
                printf ("The Stack failed\n");
                Exit (0);
        }
	cout<<&a<<endl;
        printf ("Creating son thread!!! \ n ");
        Clone (func, (char *) stack + fiber_stack,clone_vfork| CLONE_VM, 0);
        printf ("This is Father," I pid is:%d, the ' A is:%d\n ", Getpid (), a);
        Exit (1);
}

Results:

Test Code 2 (make the following modifications):

Clone (func, (char *) stack + fiber_stack,clone_vfork, 0);
Results:

Obviously, after the CLONE_VM is deleted in Test 2, the child process and the parent process do not have the common page table, and the child process creates a new page table. In a sense, clone is actually a higher level version of Fork and Vfrok, and their

This is the following (described in deep understanding of the Linux kernel):

   The Traditional fork () system call is implemented in Linux using Clone (), where the flags parameter of the clone () is specified as the SIGCHLD signal and all the clone flags for clear 0, and its child_stack parameter is the current stack of the parent process.

pointers, the parent process and child processes temporarily share a user state stack. The Vfork function system call is also implemented with clone, where the parameter flags of the Clone () are specified as SIGCHLD and Clone_vfork and CLONE_VM .

The parameter child_stack of the log, clone () equals the current stack pointer of the parent process ...

。 Just a little do not understand, the int A and void * stack into the main function, there will be a compilation error, show undefined A and stack, some do not understand, I hope the expert pointing ....



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.