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