假设我在Linux上有两个进程a
和b
。在这两个过程中,我使用malloc()
来分配内存,
malloc()
是否有可能在两个进程中返回相同的起始地址?
如果不是,那么谁来照顾这个。
如果是,则两个进程都可以访问此地址的相同数据。
答案 0 :(得分:11)
malloc()是否有可能在两个进程中返回相同的起始地址。
是的,但这不是问题。
您不理解的是操作系统首先为您处理物理空间 - 程序等只能看到虚拟地址。只有一个虚拟地址空间,然而,操作系统(现在让我们坚持使用32位)将其划分。在Windows上,上半部分(0xA0000000 +)属于内核,下半部分属于用户模式进程。这被称为2GB / 2GB分割。在Linux上,除以3GB / 1GB - 见this article:
内核内存定义为从PAGE_OFFSET开始,在x86中为0XC0000000或3千兆字节。 (这是定义3gig / 1gig拆分的地方。)PAGE_OFFSET上方的每个虚拟地址都是内核,PAGE_OFFSET下面的任何地址都是用户地址。
现在,当进程切换(而不是上下文切换)发生时,属于当前进程的所有页面都从虚拟内存中取消映射(不一定要对它们进行分页)和属于该目标的所有页面-run进程被复制(免责声明:这可能不完全正确;可以将页面标记为脏等,并在理论上复制访问权限。)
分裂的原因是,出于性能原因,虚拟内存空间的上半部分仍然可以映射到操作系统内核。
因此,尽管malloc可能在两个给定进程中返回相同的值,但这并不重要,因为:
对于64位系统,由于我们目前只使用其中的48位,因此用户模式的底部与内核模式之间存在鸿沟(尚未可寻址)。
答案 1 :(得分:2)
是的,如果进程在单独的地址空间中运行,malloc()
可以在不同的进程中返回相同的指针值,这是通过虚拟内存实现的。但是在这种情况下它们不会访问相同的物理内存位置,显然地址上的数据也不一样。
答案 2 :(得分:1)
进程是线程集合和地址空间。此地址空间称为虚拟,因为它的每个字节不一定由物理内存支持。如果进程中的应用程序最终通过有效使用此内存来最终支持虚拟地址空间的段。
因此,malloc()
可能会为两个进程返回相同的地址,但这没有问题,因为这些 malloced 内存将由不同的物理内存段支持。
此外malloc()
实现是不可重入的,因此在共享相同地址空间的不同线程中调用malloc()
有希望不会返回相同的虚拟地址。