code_tin

Copy On Write特性验证
在Windows和Linux下 为了提高复制进程的效率 会使用Copy On Write特性来产生新的进程 之前父...
扫描右侧二维码阅读全文
12
2010/01

Copy On Write特性验证

在Windows和Linux下
为了提高复制进程的效率
会使用Copy On Write特性来产生新的进程
之前父进程的变量将不会完全复制
这样导致变量会有三种情况
1.在fork之前创建的变量未被进程本身写过
则变量的值是共享的.父子进程之间都是读取一个地址的内容
2.在fork之前创建的变量被某个进程写过
则变量在这个变量被写的时候会被复制一份到这个进程的堆栈段中
3.在fork之后创建的变量
则变量在各自的堆栈段内产生.各自独立

下面是简单的例子
1.在fork之前创建变量i,fork之后创建变量j,在之后的过程中主进程只读,子进程修改

#include #include //包含O_RDONLY等宏定义 int main(void){ char test; int fd; if((fd = open("test.txt",O_RDONLY))== -1) { perror("Can't open file test.dat\n"); return 1; } printf("Open file succeed.\n"); pid_t pid; int i=0; pid=fork(); int j=0; if(pid==-1){ perror("Can't creat child process.\n"); return 1; } if( pid==0 ){ do{ printf("Child Process ID: %ld i:%d j:%d\n ",(long)getpid(),i,j); i++; j++; sleep(1); }while(1); } else{ do{ printf("Parent Process ID: %ld i:%d j:%d\n ",(long)getpid(),i,j); sleep(1); }while(1); } return 0; }

执行之后
Child Process ID: 30201 i:0 j:0 Parent Process ID: 30200 i:0 j:0 Parent Process ID: 30200 i:0 j:0 Child Process ID: 30201 i:1 j:1 Parent Process ID: 30200 i:0 j:0 Child Process ID: 30201 i:2 j:2 Parent Process ID: 30200 i:0 j:0 Child Process ID: 30201 i:3 j:3 Parent Process ID: 30200 i:0 j:0 Child Process ID: 30201 i:4 j:4
结果两种创建阶段的变量都被被独立修改.之间是分开的

2.这个例子简单修改于网上的另一个说明进程间共享fd的
主进程在fork之前打开文件
然后fork子进程一起来读
这个时候由于进程本身没有修改变量
则堆栈使用的是指向相同fd的内容
fd位置的修改工作由内核来做
所以这两个进程读出位置是相互递增的
test.txt的内容是12345

#include #include //包含O_RDONLY等宏定义 int main(void){ char test; int fd; if((fd = open("test.txt",O_RDONLY))== -1) { perror("Can't open file test.dat\n"); return 1; } printf("Open file succeed.\n"); pid_t pid; pid=fork(); if(pid==-1) { perror("Can't creat child process.\n"); return 1; } if( pid==0 ){ printf("Creat child process succeed.\n"); do{ int reads; reads=read(fd,&test,1); printf("child Process ID: %ld read:%c,reads:%d\n ",(long)getpid(),test,reads); if(reads==0){ break; } sleep(1); }while(1); close(fd); return 0; } else{ do{ int reads; reads=read(fd,&test,1); printf("parent Process ID: %ld read:%c,reads:%d\n ",(long)getpid(),test,reads); if(reads==0){ break; } sleep(1); }while(1); close(fd); return 0; } }

执行之后的结果
Open file succeed. Creat child process succeed. child Process ID: 30229 read:1,reads:1 parent Process ID: 30228 read:2,reads:1 parent Process ID: 30228 read:3,reads:1 child Process ID: 30229 read:4,reads:1 parent Process ID: 30228 read:5,reads:1 child Process ID: 30229 read:,reads:1 parent Process ID: 30228 read:5,reads:0 child Process ID: 30229 read:,reads:0
两个进程间对fd进行了共享
由于不是进程直接修改fd读取的位置
所以此值由两个进程共享.

Last modification:November 26th, 2018 at 04:16 pm
If you think my article is useful to you, please feel free to appreciate

2 comments

  1. xcch

    fork后父子进程间有些东西是共享的(比如打开的文件描述符),有些东西是不共享的(各自的变量),写时复制只是一种透明的机制,不会影响到我们常规的思维,所以我觉得你的分析有点不必要,或者说我看明白有啥亮点,我也是新手,可能看得浅。。。说错了,请指教

    1. 代码罐头
      @xcch

      不算是分析.只是自己写了给自己备忘的.

Leave a Comment