简单记录一下内核中fork的处理流程:
首先申请内存空间,并复制父进程的PCB信息及父进程的状态寄存器值,使子进程与父进程状态保持一致。
首先申请内存空间,并复制父进程的PCB信息及父进程的状态寄存器值,使子进程与父进程状态保持一致。
然后,确定新进程的地址空间,复制父进程的LDT信息,保持父子进程的代码段,数据段位置一致。
接着,复制父进程的页目录项及页表。
来个小程序说明进程复制过程:
#include <stdio.h>
#include <sched.h>
int data = 10;
int child_process()
{
printf("Child process %d, data %d, &data = %d\n",getpid(),data, &data);
data = 20;
printf("Child process %d, data %d, &data = %d\n",getpid(),data, &data);
while(1);
}
int main(int argc, char* argv[])
{
if(fork()==0) {
child_process();
}
else{
sleep(1);
printf("Parent process %d, data %d, &data = %d\n",getpid(), data, &data);
while(1);
}
return 0;
}
最后结果是当子进程修改data值之前,data内容保持一致。当子进程企图修改data值时,系统产生缺页异常,内核重新
为子进程分配内存地址,并将分配的内存与新进程的地址空间绑定。
这样在新进程看来相同的位置,其实映射到了不同的物理内存上。
这就是父子进程输出的地址相同的原因了。