Because of the complexity of life, this is a parallel world, at the same time, there will be a lot of wonderful things, the North snow, the South rain, here in the dinner, there in the sleep, someone in the study, someone in the movement, so at this moment a colorful world, a lot of things happen every day, so want to show the world very well To coordinate the completion of one thing, you need to use multi-process or multi-threading. So the process is a program ape must be exposed to a thing, he can make our program efficiency improvement, efficient completion of multi-tasking, parallel execution. Here's a look at the three functions that produce a process or thread.
Fork,vfork,clone are Linux system calls, these three functions call the Sys_fork, Sys_vfork, Sys_clone, and finally call the Do_fork function, the difference is the transfer of parameters and some basic preparation work is different, Used primarily for Linux to create new child processes or threads (vfork creates threads).
four elements of a process:
(1) There is a procedure for its execution (not necessarily a process-specific), as a play must have its own script.
(2) has its own dedicated system stack space (private property)
(3) with Process Control block (task_struct) ("id, PID")
(4) There is a separate storage space.
Missing fourth is called a thread, and if there is no user space at all called a kernel thread, the shared user space is called the user thread.
First, fork ()
Fork () function call succeeded: returns two values; parent process: Returns the PID of the child process; child process: returns 0;
Failure: return-1;
The sub-process created by fork replicates the resources of the Father process (copy-on-write technology), including the contents of the Memory task_struct content (2 different PID of the process). Here is a copy of the resource that is not a pointer.
When it comes to fork (), you have to say a technique:(copy-on-write) copy-on-write technology.
stealing a picture, feeling the description is really quite in place:
We all know that when fork creates a process, there is no real copy memory (sounds like a contradiction, why is the assignment of a resource really assigned?) Because we know that for fork, there is a nasty thing called the exec series system call, it will seduce the sub-process to reinvent the line. If a child process is created with a memory copy, the hard copy memory is completely discarded once exec is executed. Since fork () produces a child process that is exactly the same as the parent process, the child process will then exec the system call, and in efficiency, Linux introduces "copy-on-write technology-copy-on-write".
In other words, before exec two processes use the same physical space (memory area) after the fork (), the page table mapping relationship is set up and the memory is not actually copied. The code snippet, data segment, and stack of the child process are the physical spaces that point to the parent process, that is, the virtual space for the two is different, but the corresponding physical space is the same. When the parent process has changed the behavior of the corresponding segment occurs, such as process write access, and then allocate physical space for the corresponding segment of the child process, if it is not for exec, the kernel assigns the corresponding physical space to the child process's data segment, stack segment (at which point each has its own process space and does not affect each other). The code snippet continues to share the physical space of the parent process (the code is exactly the same). And if it is because of exec, the code snippet for the child process will also be assigned a separate physical space because of the different code executed by the two. When a child process is fork, the parent process data space, heap, and stack are copied so that the address of the variable (of course, the virtual address) is the same.
The exact process is this:
Fork child process completely copy the stack space of the parent process, but also copy the page table, but not the physical page, so the virtual address is the same, the physical address is the same, but the parent-child shared page is marked as "read-only", if the parent-child process has been on this page is the same page, Until any of these processes "write" to the shared page, the kernel copies a physical page for the process to use and modifies the page table. Instead, the original read-only page is marked as "writable" and left for another process to use. This is called "copy-on-write".
In understanding: After fork, the two same virtual addresses point to a different physical address, which facilitates understanding the independence of the parent process.
but in fact, LInux in order to improve the efficiency of fork, using the Copy-on-write technology, after fork, these two virtual addresses actually point to the same physical address. (Memory page), two virtual addresses point to a different physical address before any one process attempts to modify the contents of the virtual address. The contents of the new physical address are copied from the source physical address.
problem: Fork uses this mechanism of write-time replication, then fork out the sub-process, the theoretical sub-process and the parent process that the first dispatch (theoretical efficiency analysis, the individual feel that there is a certain truth)?
After fork, the kernel typically puts the child process in front of the queue so that the child process executes first, because in many cases the process executes the exec immediately, emptying the stack, the heap, the space shared by the parent process, and loading the new code snippet. This avoids the chance that the parent process will copy the shared page on write. If the parent process first dispatches the most likely to write a shared page, and the child process does nothing, it produces a "copy-on-write" without effort. Therefore, the general child process is dispatched first. Avoid the loss of efficiency due to meaningless duplication.
Let's look at an example:
#include "stdio.h" int main () {int count = 1;int child;if (0== Fork ())///child process successfully returned 0;{//start creating child process printf ("This is son, his count I S:%d. And his PID are:%d\n ", ++count, Getpid ());//The contents of the child process} else {printf (" This is father, he count is:%d, he pid is:%d\ N ", Count, Getpid ());}}
Operation Result:
From the results, you can see that the child process and the parent processdifferent PID, the memory resource count is worth copying, and the child process has changed the value of count, while the count in the parent process has not been changed. Some people think that such a large volume of replication can lead to inefficient execution. In fact, during the copy process, the child process copies the parent process's task_struct, the system stack space and the page table, which means that the above program, we did not execute count++ before, actually the child process and the parent process of the count point is the same piece of memory. When a child process changes the variables of the parent process, theCopy_on_writeTo create a new copy of the page involved. So when we execute ++count, this time the child process creates a new page to copy the contents of the original page.replication of basic resources is a must, and is efficient。 The whole looks like a separate storage space for the parent process, and it's replicated again. This will be a certain difference from the vfork below.
Second, we see that the child process and the parent process directlywithout interfering with each other, obviously 2 peopleResources are independentThe Let's see the procedure below.
#include "stdio.h" int main () { int count = 1; int child; int i; if (! ( Child = Fork ()) } { for (i = 0; I <20; i++) { printf ("This is son, he count is:%d. And he pid is:%d\n ", I, Getpid ()); } } else {for (i=0;i<20;i++) printf ("This is father, he count is:%d, he pid is:%d\n", Count, Getpid ()); c16/>}}
Operation Result:
From the running results can be seen that the parent-child 2 processes are running synchronously,In fact, in no particular order。
Second, vfork ()
Vfork is an outdated application, and vfork is also creating a child process, but the child process shares the space of the parent process. After Vfork creates a child process, the parent process blocks until the child process executes exec () or exit (). Vfork originally because the fork did not implement the cow mechanism, and in many cases the fork will be followed by exec, and exec execution equivalent to the previous fork copy of the space to become useless, so designed vfork. now fork uses the cow mechanism, the only price is the cost of copying the parent Process page table, so vfork should not appear in the new code.
Vfork is created not by a real process, but by a thread, because it lacks a regular feature (4), a separate memory resource , to see the following program:
#include "stdio.h" int main () { int count = 1; int child; printf ("Before create son, the Father ' s Count is:%d\n", count); if (! ( Child = Vfork ()) } { printf ("This was son, his PID was:%d and the count is:%d\n", Getpid (), ++count); Exit (1); } else { printf ("After son, this is father, he pid is:%d and the count are:%d, and the child is:%d\n", Getpid (), count, child);} }
Operation Result:
From the running result, you can see that the child process created by vfork (thread) shares the count variable of the parent process, which is a pointer copy , and the pointer to 2 points to the same memory, so the child process modifies the count variable, and the count variable of the parent process is also affected.
In addition, the child process created by Vfork is executed before the parent process, and when the child process executes, the parent process is suspended, the child process finishes executing, and the parent process wakes up. unless the child process exit or EXECVE will invoke the parent process , see the following program:
#include "stdio.h" int main () { int count = 1; int child; printf ("Before create son, the Father ' s Count is:%d\n", count); if (! ( Child = Vfork ())) { int i; for (i = 0; i < +; i++) { printf ("This was son, the I is:%d\n", i); count++; if (i = =) { printf ("This was son, his PID was:%d and the count is:%d\n", Getpid (), ++count); Exit (1); }} else { printf ("After son, this is father, he pid is:%d and the count are:%d, and the child is:%d\n", Getpid () , count, child);} }
Operation Result:
From the result of the run, you can see that the parent process is always waiting for the child process to finish before it starts to execute.
3.clone
Clone is a set of Linux for creating Threads (although you can also create a process with clone). so it can be said that clone is an upgraded version of fork, not only to create a process or thread, but also to specify the creation of a new namespace (namespace), a selective memory to inherit from the parent process, and even a sibling process that can turn the created process into a parent process , and so on.
The Clone function is powerful, with a number of parameters, and it provides a very flexible way to free common processes. So the process created by him is more complex than the previous 2 methods. Clone allows you to selectively inherit the resources of the parent process , and you can choose to share a virtual space with the parent process like vfork, thus creating a thread that you can not share with the parent process , you can even choose to create the process and the parent process is no longer A father-son relationship, but a brotherhood. first it is necessary to say the structure of this function:
int Clone (int (*FN) (void *), void *child_stack, int flags, void *arg);
fn is a function pointer, this pointer points to a function body, the static program that wants to create the process (we know the 4 elements of the process, this is the pointer to the program, the so-called "script");
Child_stackTo assign a pointer to a system stack to a child process (in Linux, the system stack space is 2 pages, which is 8K of memory, in which the value is placed in the low address, which is the value of the Process Control block task_struct);
ArgIs that the parameters passed to the child process are generally (0);
FlagsFor the flags that you want to copy resources from, describe the resources you need to inherit from the parent process (resource replication or sharing, set parameters here:
Here is the value that flags can take
Logo meaning
The parent process of the child process created by Clone_parent is the parent of the caller, and the new process and the process that created it become "brothers" rather than "father and son"
The CLONE_FS child process shares the same file system as the parent process, including root, current directory, umask
Clone_files child processes share the same file descriptor (descriptor) table as the parent process
Clone_newns starts the subprocess in the new namespace, namespace describes the process's files hierarchy
Clone_sighand child processes share the same signal processing (signal handler) table as the parent process
Clone_ptrace If the parent process is trace, the child process is also trace
Clone_vfork The parent process is suspended until the child process frees the virtual memory resource
CLONE_VM child processes run in the same memory space as the parent process
The Clone_pid child process is created with the same PID as the parent process
Clone_thread Linux 2.4 is added to support POSIX threading standards, and child processes share the same lines as the parent process Cheng
The following example creates a thread (the child process shares the virtual memory space of the parent process and does not have its own independent virtual storage space that cannot be called a process). The parent process is suspended when the sub-thread frees the virtual storage resource before continuing execution .
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <sched.h> #define Fiber_ STACK 8192int a;void * stack;int do_something () {a=10;printf ("This was son, the PID is:%d, the A is:%d\n", Getpid (), a); fre E (stack); Exit (1);} int main () {void * Stack;a = 1;stack = malloc (fiber_stack);//Request System stack for child process if (!stack) {printf ("the Stack failed\n"); exit (0);} printf ("Creating son thread!!! \ n "); Clone (&do_something, (char *) stack + fiber_stack, clone_vm| Clone_vfork, 0);//Create a child thread printf ("This is father, my pid is:%d, the A is:%d\n", Getpid (), a); exit (1);}
Results of the operation:
Son's pid:10692;
The pid:10691 of Father;
Both parent and son A are 10; so they prove they're common. Variable A, which is a copy of the pointer, rather than a copy of the value.
Question: The difference between clone and fork:
(1) Clone and Fork are called in a very different way, and the clone call needs to pass in a function that executes in the child process.
(2)The biggest difference between clone and fork is that clone no longer replicates the stack space of the parent process, but instead creates a new one. (void *child_stack,) is the second parameter, which requires allocating the space of the stack pointer, so it is no longer inherited or duplicated, but a new creation.
Blog Material Reference:
http://blog.csdn.net/xy010902100449/article/details/44851453
Http://www.cnblogs.com/blankqdb/archive/2012/08/23/2652386.html
Http://blog.chinaunix.net/uid-24774106-id-3361500.html
Http://www.linuxidc.com/Linux/2015-03/114888.htm
http://igaozh.iteye.com/blog/1677969
Http://blog.chinaunix.net/uid-24410388-id-195503.html
Http://blog.chinaunix.net/uid-18921523-id-265538.html
http://blog.csdn.net/wdjhzw/article/details/25614969
Thank you bloggers for sharing!
The difference between fork (), Vfork (), Clone ()