I want to know how copy-on-write happens in fork().
Assuming we have a process A that has a dynamical int array:
int *array = malloc(1000000*sizeof(int));
Elements in array are initialized to some meaningful values. Then, we use fork() to create a child process, namely B. B will iterate the array and do some calculations:
for(a in array){
a = a+1;
}
- I know B will not copy the entire array immediately, but when does the child B allocate memory for array? during fork()?
- Does it allocate the entire array all at once, or only a single integer for
a = a+1
? a = a+1;
how does this happen? Does B read data from A and write new data to its own array?
I wrote some code to explore how COW works. My environment: 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;
}
After fork(), the child process modifies a half of numbers in array, and then modifies the entire array. The outputs are:
===
Total: 16694571008
Free: 2129162240
===
Total: 16694571008
Free: 2126106624
===
Total: 16694571008
Free: 1325101056
===
Total: 16694571008
Free: 533794816
It seems that the array is not allocated as a whole. If I slightly change the first modification phase to:
i = 0;
for(; i<len/2; i++){
array[i*2] = i+1;
}
The outputs will be:
===
Total: 16694571008
Free: 2129924096
===
Total: 16694571008
Free: 2126868480
===
Total: 16694571008
Free: 526987264
===
Total: 16694571008
Free: 526987264