为什么变量的地址在修改后的fork()系统调用中保持相同

时间:2012-05-23 08:26:22

标签: operating-system

请考虑以下代码段。

if (fork() == 0)
{
     a = a + 5;
     printf("%d, %d \n", a, &a);
}
else
{
     a = a - 5;
     printf ("%d, %d \n", a,& a);
}

AFAIK,当创建fork()时,父级的虚拟地址空间被复制到子级,并且子级& parent共享相同的物理页面,直到其中一个尝试修改。当下其中一个孩子& parent修改变量,将parent的物理页面复制到子页面的另一个页面,并且物理页面保持私有。 所以,这里'a'的值在child&中是不同的。家长。但是当涉及到儿童和儿童的'a'地址时父级,输出相同。即使物理页面不同,我也无法弄清楚为什么地址保持不变。

2 个答案:

答案 0 :(得分:7)

a的地址不是实际的实际地址。

这是一个虚拟地址 硬件/操作系统层将虚拟地址映射到物理地址(无形地映射到您的应用程序)。

因此,即使地址具有相同的number,它们也不会映射到ram芯片上的相同物理内存。

PS。使用printf()打印地址(即指针)时最好使用“%p”

答案 1 :(得分:3)

响应几乎在您的问题中:修改a后,a的物理页面被复制(因此与父进程中的不同),但是虚拟地址(由您的程序通过&a)不会改变。

事实上,在为a分配新值时更改a的虚拟地址会非常尴尬。考虑如果您之前存储了指向 int *p = &a; a = a - 5; printf("%d", *p) 的指针会发生什么:

a

在第二行p之后不再指向{{1}},这是一种程序员不会期望的行为。

对物理页面使用copy-on-write是对程序行为无关的操作系统的优化:您可以考虑在分叉时复制整个地址空间。