Почему оба процесса (родительский и дочерний) указывают на один и тот же код и сегмент данных? - PullRequest
1 голос
/ 06 августа 2020

Я попытался создать дочерний процесс с помощью fork () и попытался проверить код и сегмент данных дочернего процесса. Но оба процесса указывают на одно и то же место.

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>

static int global_var = 10;

void increment(int *var){
        printf("Incrementing @%p\n", var);
        *var += 1;
}

void decrement(int *var){
        printf("Decrementing @%p\n", var);
        *var -= 1;
}

void do_operation(void (*my_ops)(int *)){

        my_ops(&global_var);
        printf("@Adr=0x%p, Global Val = %d\n", &global_var, global_var);
}


int main(){

        int i, local_var;
        pid_t pid;
        pid = fork();

        switch(pid){

                case -1:
                        printf("Failed to create new Process.\n");
                        break;
                case 0:
                        printf("Calling do_operation(), which is @%p\n", &do_operation);
                        for(i=0; i<5; i++){
                                printf("Child Process with pid(%d), ", getpid());
                                do_operation(&decrement);
                                sleep(1);
                        }
                        break;

                default:
                        printf("Calling do_operation(), which is @%p\n", &do_operation);
                        for(i=0; i<5; i++){
                                printf("Parent Process with pid(%d), ", getpid());
                                do_operation(&increment);
                                sleep(1);
                        }
                        wait(NULL);
                        break;
        }

        return 0;
}

Сегмент кода и сегмент данных обоих процессов указывают на один и тот же адрес. Вы можете увидеть следующий вывод.

Calling do_operation(), which is @0x55d37fd34846
Parent Process with pid(2718), Incrementing @0x55d37ff35010
@Adr=0x0x55d37ff35010, Global Val = 11
Calling do_operation(), which is @0x55d37fd34846
Child Process with pid(2719), Decrementing @0x55d37ff35010
@Adr=0x0x55d37ff35010, Global Val = 9
Parent Process with pid(2718), Incrementing @0x55d37ff35010
@Adr=0x0x55d37ff35010, Global Val = 12
Child Process with pid(2719), Decrementing @0x55d37ff35010
@Adr=0x0x55d37ff35010, Global Val = 8
Parent Process with pid(2718), Incrementing @0x55d37ff35010
@Adr=0x0x55d37ff35010, Global Val = 13
Child Process with pid(2719), Decrementing @0x55d37ff35010
@Adr=0x0x55d37ff35010, Global Val = 7
Parent Process with pid(2718), Incrementing @0x55d37ff35010
@Adr=0x0x55d37ff35010, Global Val = 14
Child Process with pid(2719), Decrementing @0x55d37ff35010
@Adr=0x0x55d37ff35010, Global Val = 6
Parent Process with pid(2718), Incrementing @0x55d37ff35010
@Adr=0x0x55d37ff35010, Global Val = 15
Child Process with pid(2719), Decrementing @0x55d37ff35010
@Adr=0x0x55d37ff35010, Global Val = 5

Вы можете видеть, что адреса переменной stati c в обоих процессах одинаковы. Почему это?

1 Ответ

4 голосов
/ 06 августа 2020

В большинстве современных операционных систем каждый процесс имеет собственное виртуальное адресное пространство . Следовательно, даже если два процесса используют один и тот же адрес виртуальной памяти, это не означает, что эти виртуальные адреса отображаются на один и тот же физический адрес памяти.

При разветвлении процесса отображение страницы виртуальной памяти для страниц физической памяти, вероятно, останутся прежними, за исключением того, что копирование при записи активировано для всех страниц памяти. Таким образом, если один процесс изменяет страницу памяти, оба процесса получают свою собственную копию этой страницы памяти в физической памяти. В этом случае адреса виртуальной памяти в обоих процессах останутся такими же, но адреса физической памяти будут разными.

...