以下是我对fork()的理解: fork()系统调用从父进程旋转子进程。子进程的核心映像(地址空间)是父进程的核心映像(地址空间)的精确副本。地址空间包含:
但是副本实际上并没有完成,直到其中一个进程(父或子)开始写入其地址空间。只有在孩子被分配一个单独的地址空间时才会这样。
我写了一个程序来测试我的理解,结果显示我可能会遗漏一些东西:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid=fork();
int a=5;
if(pid<0){/*error condition*/
printf("Error forking\n");
}
if(pid==0){/*child process*/
printf("Child process here\n");
a=a+5;
printf("The value of a is %d\n",a);
printf("The address of a is %p\n",&a);
printf("Child terminated\n");
exit(getpid()); /*child terminates*/
}
else{/*parent process*/
printf("Parent blocked\n");
wait(NULL); /*waiting for child process to exit*/
printf("Parent process here");
printf("The value of a is %d\n",a);
printf("The address of a is %p\n",&a);
printf("parent terminated");
}
}
以下是上述程序的输出:
Parent blocked
Child process here
The value of a is 10
The address of a is 0x7ffe4c37b1a0
Child terminated
Parent process hereThe value of a is 5
The address of a is 0x7ffe4c37b1a0
有人可以向我解释为什么两个地址都相同吗?由于子进程更新了其变量,因此应为其分配一个单独的内存位置。
答案 0 :(得分:3)
不是这样。
孩子和父母看到的地址都与他们自己的地址空间有关,而不是相对于整个系统。
操作系统将每个进程使用的内存映射到物理(或虚拟)内存中的不同位置。但是该过程看不到该映射。
答案 1 :(得分:1)
但是副本实际上并没有完成,直到其中一个进程(父或子)开始写入其地址空间。只有这样才能为孩子分配一个单独的地址空间。
Linux就是这样做的,但不是所有的Eunuchs变种都这样做。
有人可以向我解释为什么两个地址都相同吗?
在现代操作系统中,每个进程都有自己的逻辑地址空间,页面映射到物理页面帧。除了专用于系统的地址和明确共享的地址外,每个进程中的相同地址都映射到不同的物理地址。
父级的逻辑地址0x7ffe4c37b1a0映射到与子级0x7ffe4c37b1a0不同的物理地址。