指向不同值的相同地址 - fork 系统调用

Same addresses pointing to different values - fork system call

调用fork时,栈和堆都从父进程复制到子进程。在使用 fork 系统调用之前,我 malloc() 一些内存;假设它的地址是 A。在使用 fork 系统调用之后,我在父进程和子进程中打印了这块内存的地址。我看到两者都在打印相同的地址: A. 子进程和父进程能够独立地向该地址写入任何值,并且一个进程的修改不会反映在另一个进程中。据我所知,地址在一台机器中是全局唯一的。

我的问题是:为什么同一个地址location A同时存储了不同的值,即使复制了堆?

"real"内存地址和你平时使用的内存地址是有区别的,即"virtual"内存地址。虚拟内存基本上只是操作系统的抽象,以便管理不同的页面,这允许 OS 将页面从 RAM 切换到 HDD (page file),反之亦然。

这允许 OS 即使在达到 RAM 容量时也能继续运行,并在不更改程序逻辑的情况下将相关页面文件放入 RAM 中的随机位置(否则,指向 0x1234 的指针发生页面切换后会突然指向 0x4321)。

如果您分叉您的进程基本上只是页面文件的副本,我认为这允许更智能的算法发生,例如仅当一个进程实际修改页面文件时才复制。

要提到的一个重要方面是分叉 不应该 更改任何内存地址,因为(例如在 C 中)您的应用程序中可能有相当多的指针逻辑,依赖关于您分配的内存的一致性。如果地址在分叉后突然改变,它会破坏大部分(如果不是全部的话)指针逻辑。

您可以在此处阅读更多相关信息:http://en.wikipedia.org/wiki/Virtual_memory or, if you're truly interested, I recommend reading "Operating Systems - Internals and Design Principles" by William Stallings, which should cover most things including why and how virtual memory is used. There is also an excellent answer to this in this Whosebug thread. Lastly, you might want to also read answers from this, this and this 问题。