【发布时间】:2020-08-31 18:13:08
【问题描述】:
fork 后子进程的虚拟地址空间在幕后发生了什么?
我一直在阅读其他帖子,但有些人所说的与其他人所说的相反,这有点搞砸了我的想法。
以这段代码为例:
int main(int argc, char const *argv[])
{
int a = 5;
dummy(&a);
return 0;
}
void dummy(int * a){
if(fork()==0){
printf("%p",a);
*a=10;
}
else{
printf("%p",a);
printf("%d\n",*a); //a is still 5
}
}
为什么%p 的值在两个 printf 之后都相同,但是当我在子节点中更改 a 的值时,它不会反映在父节点上。打印%p时,是指变量的虚拟地址?
子节点的虚拟地址是否与父节点相同(在对堆进行任何更改之前), 或者新的子进程有自己的虚拟地址,指向父进程的相同物理地址(只要堆中的变量没有改变)?
我读到,当对位于子堆上的变量进行更改时,物理内存被克隆,虚拟地址现在指向这个新克隆的物理地址(现在变量已更改)——一个进程称为写时复制。
【问题讨论】:
-
您看到的所有地址都是虚拟的。物理地址对您的程序完全隐藏。除非您正在编写操作系统内核,否则它们并不重要。分叉进程的内存是父进程内存的精确副本。这包括所有事物的地址。
-
如果你想查看实际的物理地址,要么使用现有的操作系统内核,要么使用一些 MS-DOS 实模式程序(因为实模式不支持内存虚拟化(有一些小警告) ),那里使用的地址是实际的物理内存地址。
标签: c