我想知道 fork() 中的写时复制是如何发生的。
假设我们有一个具有动态 int 数组的进程 A:
int *array = malloc(1000000*sizeof(int));
数组中的元素被初始化为一些有意义的值。然后,我们使用fork()创建一个子进程,即B。B会迭代数组并做一些计算:
for(a in array){
a = a+1;
}
- 我知道 B 不会立即复制整个数组,但是子 B 什么时候为数组分配内存?在 fork() 期间?
- 它是一次分配整个数组,还是只分配一个整数
a = a+1
? a = a+1;
这是怎么发生的?B 是否从 A 读取数据并将新数据写入自己的数组?
我写了一些代码来探索 COW 是如何工作的。我的环境:ubuntu 14.04、gcc4.8.2
#include <stdlib.h>
#include <stdio.h>
#include <sys/sysinfo.h>
void printMemStat(){
struct sysinfo si;
sysinfo(&si);
printf("===\n");
printf("Total: %llu\n", si.totalram);
printf("Free: %llu\n", si.freeram);
}
int main(){
long len = 200000000;
long *array = malloc(len*sizeof(long));
long i = 0;
for(; i<len; i++){
array[i] = i;
}
printMemStat();
if(fork()==0){
/*child*/
printMemStat();
i = 0;
for(; i<len/2; i++){
array[i] = i+1;
}
printMemStat();
i = 0;
for(; i<len; i++){
array[i] = i+1;
}
printMemStat();
}else{
/*parent*/
int times=10;
while(times-- > 0){
sleep(1);
}
}
return 0;
}
在fork()之后,子进程修改数组中的一半数字,然后修改整个数组。输出是:
===
Total: 16694571008
Free: 2129162240
===
Total: 16694571008
Free: 2126106624
===
Total: 16694571008
Free: 1325101056
===
Total: 16694571008
Free: 533794816
似乎数组没有作为一个整体分配。如果我将第一个修改阶段稍微更改为:
i = 0;
for(; i<len/2; i++){
array[i*2] = i+1;
}
输出将是:
===
Total: 16694571008
Free: 2129924096
===
Total: 16694571008
Free: 2126868480
===
Total: 16694571008
Free: 526987264
===
Total: 16694571008
Free: 526987264