4

假设我有两个进程a并且b在 Linux 上。在这两个过程中我都malloc()用来分配内存,

有没有机会malloc()在两个进程中返回相同的起始地址?如果没有,那么谁来处理这件事。如果是,则两个进程都可以访问此地址的相同数据。

4

3 回答 3

12

malloc() 是否有可能在两个进程中返回相同的起始地址。

是的,但这不是问题。

您不了解的是操作系统首先为您处理您的物理空间 - 程序等只看到虚拟地址。只有一个虚拟地址空间,但是,操作系统(让我们暂时坚持使用 32 位)将其划分。在 Windows 上,上半部分 (0xA0000000+) 属于内核,下半部分属于用户模式进程。这称为 2GB/2GB 拆分。在 Linux 上,划分为 3GB/1GB - 请参阅这篇文章

内核内存定义为从 PAGE_OFFSET 开始,在 x86 中为 0XC0000000,即 3 GB。(这是定义 3gig/1gig 拆分的地方。) PAGE_OFFSET 之上的每个虚拟地址都是内核,PAGE_OFFSET 之下的任何地址都是用户地址。

现在,当发生进程切换(与上下文切换相反)时,属于当前进程的所有页面都从虚拟内存中取消映射(不一定对它们进行分页),并且所有属于要运行的进程的页面被复制进来(免责声明:这可能不完全正确;理论上可以将页面标记为脏等并在访问时复制)。

拆分的原因是,出于性能原因,虚拟内存空间的上半部分可以保持映射到操作系统内核。

因此,尽管 malloc 可能在两个给定进程中返回相同的值,但这并不重要,因为:

  1. 物理上,它们不是同一个地址。
  2. 这些进程不会在任何地方共享虚拟内存。

对于 64 位系统,由于我们目前只使用其中的 48 位,因此在用户模式的底部和内核模式之间存在一个无法寻址的鸿沟(目前)。

于 2012-07-04T12:20:11.510 回答
2

malloc()的,如果进程在不同的地址空间中运行,则可以在不同的进程中返回相同的指针值,这是通过虚拟内存实现的。但在这种情况下,它们不会访问相同的物理内存位置,并且地址处的数据显然不必相同。

于 2012-07-04T12:17:14.170 回答
1

进程是线程的集合加上地址空间。这个地址空间被称为虚拟地址空间,因为它的每个字节都不一定由物理内存支持。如果进程中的应用程序最终有效地使用了该内存,则虚拟地址空间的段最终将由物理内存支持。

因此,malloc()可能会为两个进程返回相同的地址,但这没有问题,因为这些分配的内存将由不同的物理内存段支持。

此外malloc(),实现大部分是不可重入的,因此malloc()在共享相同地址空间的不同线程中调用希望不会导致返回相同的虚拟地址。

于 2012-07-04T12:48:56.537 回答