【问题标题】:Same addresses pointing to different values - fork system call相同的地址指向不同的值——fork 系统调用
【发布时间】:2015-06-09 08:15:33
【问题描述】:

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

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

【问题讨论】:

    标签: fork


    【解决方案1】:

    “真实”内存地址与您通常使用的内存地址(即“虚拟”内存地址)之间存在差异。虚拟内存基本上只是操作系统的抽象,用于管理不同的页面,这允许操作系统将页面从 RAM 切换到 HDD (page file),反之亦然。

    这允许操作系统在达到 RAM 容量的情况下继续运行,并将相关的页面文件放入 RAM 内的随机位置而不改变程序的逻辑(否则,指向 0x1234 的指针会在之后突然指向 0x4321发生了页面切换)。

    如果你 fork 你的进程基本上只是页面文件的副本,会发生什么——我假设——这允许更智能的算法发生,例如仅当一个进程实际修改页面文件时才进行复制。

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

    您可以在此处阅读更多信息:http://en.wikipedia.org/wiki/Virtual_memory,或者,如果您真的感兴趣,我建议您阅读 William Stallings 的“操作系统 - 内部结构和设计原则”,其中应该涵盖大部分内容,包括虚拟内存的原因和方式用来。在this StackOverflow thread 中也有一个很好的答案。最后,您可能还想阅读来自thisthisthis 问题的答案。

    【讨论】:

    • 感谢您的回答,您是说父进程和子进程虽然显示相同的地址 A,但在较低级别,它们是不同的内存位置,每个进程可以独立访问。
    • 确实,尽管操作系统可能会应用一些幕后魔法来节省性能(仅在实际修改内存时才复制内存等)。但是,在普通应用程序中,您无法访问此类信息,因此您可以放心地假设它们都指向不同的“真实”内存地址,尽管它们具有相同的“显示”地址。
    猜你喜欢
    • 2016-10-06
    • 2021-02-18
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 2019-05-13
    • 1970-01-01
    • 2019-09-07
    • 1970-01-01
    相关资源
    最近更新 更多