In Linux, fork () is implemented using copy-on-write. Copy at write time is a technology that can delay or even avoid copying data. At this time, the kernel does not copy the address space of the entire process, but shares the same address space with the parent and child processes.
A Linux Process is created. The sub-Process certifies the "copy upon write" of the parent process resource.
The traditional fork () system calls directly copy all the resources to the newly created process. This implementation is too simple and inefficient, because the data it copies may be shared (this approach is significantly na? Ve and inefficient in that it copies much data that might otherwise be shared .). Even worse, if the new process intends to execute a new image immediately, all the copies will be discarded.
In Linux, fork () uses the copy-on-write page. Copy at write time is a technology that can delay or even avoid copying data. At this time, the kernel does not copy the address space of the entire process, but shares the same address space with the parent and child processes. The address space is copied only when data needs to be written, so that each operation has its own address space. That is to say, the replication of resources is performed only when the data needs to be written. Before that, the resources can only be shared in read-only mode. This technology delays the copy of pages in the address space until the actual writing occurs. When the page is not written at all-for example, execute exec () immediately after fork (), address space
No need to be copied. The actual overhead of Fork () is to copy the page table of the parent process and create a process descriptor for the child process. The following program certifies the copy at write time:
#include <stdio.h>#include <sched.h>int data = 10;int child_process(){printf("Child process %d, data %dn",getpid(),data);data = 20;printf("Child process %d, data %dn",getpid(),data);while(1);}int main(int argc, char* argv[]){if(fork()==0) {child_process(); }else{sleep(1);printf("Parent process %d, data %dn",getpid(), data);while(1);}}
Running result
Child process 6427, data 10
Child process 6427, data 20
Parent process 6426, data 10
1st child process 6427, data 10 is because the mm of task_struct is directly copied from the mm of parent when the child process is created; 2nd child process 6427, data 20 is because the sub-process performs "Copy at write time" and has its own dataa; 3rd parent process 6426, data 10 outputs 10 because the data of the child process is not the same as that of the parent process.
If you change the above program:
#include <stdio.h>#include <sched.h>#include <stdlib.h>int data = 10;int child_process(){printf("Child process %d, data %dn",getpid(),data);data = 20;printf("Child process %d, data %dn",getpid(),data);while(1);}int main(int argc, char* argv[]){void **child_stack;child_stack = (void **) malloc(16384);clone(child_process, child_stack, CLONE_VM|CLONE_FILES|CLONE_SIGHAND, NULL);sleep(1);printf("Parent process %d, data %dn",getpid(), data);while(1);}
The running result will be
Child process 6443, data 10
Child process 6443, data 20
Parent process 6442, data 20
Since clone_vm is used to create a process, the mm of the child process actually points directly to the mm of the parent process, so data is the same. The data that changes the Parent and Child processes will be visible to each other.