Wie funktioniert das Kopieren beim Schreiben in fork ()?

Ich möchte wissen, wie Copy-on-Write in fork () abläuft.

ngenommen, wir haben einen Prozess A mit einem dynamischen int-Array:

int *array = malloc(1000000*sizeof(int));

Elemente im Array werden auf einige sinnvolle Werte initialisiert. Dann erstellen wir mit fork () einen untergeordneten Prozess, nämlich B. B iteriert das Array und führt einige Berechnungen durch:

for(a in array){
    a = a+1;
}
Ich weiß, B kopiert nicht sofort das gesamte Array, aber wann weist das untergeordnete B dem Array Speicher zu? während fork ()? Weist es das gesamte Array auf einmal zu oder nur eine einzelne Ganzzahl füra = a+1?a = a+1; wie kommt es dazu? Liest B Daten von A und schreibt neue Daten in sein eigenes Array?

Ich habe Code geschrieben, um herauszufinden, wie COW funktioniert. Meine Umgebung: 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;
}

Nach fork () ändert der untergeordnete Prozess eine Hälfte der Zahlen im Array und anschließend das gesamte Array. Die Ausgänge sind:

===
Total: 16694571008
Free: 2129162240
===
Total: 16694571008
Free: 2126106624
===
Total: 16694571008
Free: 1325101056
===
Total: 16694571008
Free: 533794816

Es scheint, dass das Array nicht als Ganzes zugeordnet ist. Wenn ich die erste Änderungsphase leicht ändere in:

i = 0;
for(; i<len/2; i++){
    array[i*2] = i+1;
}

Die Ausgaben werden sein:

===
Total: 16694571008
Free: 2129924096
===
Total: 16694571008
Free: 2126868480
===
Total: 16694571008
Free: 526987264
===
Total: 16694571008
Free: 526987264

Antworten auf die Frage(4)

Ihre Antwort auf die Frage