1

我不太明白“多个独立的虚拟地址,指向同一个物理地址”的好处,尽管我读了很多书和帖子,

例如,在类似的问题中物理寻址和虚拟寻址概念之间的区别

该帖子声称该程序不会相互崩溃,并且

“一般来说,一个特定的物理页面只映射到一个应用程序的虚拟空间”

好吧,在http://tldp.org/LDP/tlk/mm/memory.html的“共享虚拟内存”部分,它说

“例如,系统中可能有多个进程运行 bash 命令 shell。与其拥有多个 bash 副本,每个进程在虚拟地址空间中都有一个,不如在物理内存中只有一个副本并且所有进程都在运行bash 分享它。”

如果一个物理地址(例如,shell 程序)映射到两个独立的虚拟地址,这怎么能不崩溃呢?与使用物理寻址不一样吗?

虚拟寻址提供什么,物理寻址不可能或不方便?如果不存在虚拟内存,即两个直接指向同一个物理内存?我认为,通过使用一些协调机制,它仍然可以工作。那么为什么要打扰“虚拟寻址、MMU、虚拟内存”这些东西呢?

4

2 回答 2

4

此功能有两个主要用途。

首先,您可以在进程之间共享内存,这些进程可以通过共享页面进行通信。事实上,共享内存是最简单的 IPC 形式之一。

但是共享只读页面也可以用来避免无用的重复:大多数情况下,程序的代码在加载到内存后不会改变,因此它的内存页面可以在运行该程序的所有进程之间共享。显然只有代码是共享的,包含堆栈、堆的内存页面以及程序的一般数据(或者,如果您愿意,状态)是不共享的。

这个技巧通过“写时复制”得到了改进。可执行文件的代码在运行时通常不会改变,但有些程序实际上是自我修改的(它们在过去很常见,当时大部分开发仍以汇编方式完成);为了支持这些东西,操作系统会像之前解释的那样进行只读共享,但是,如果它检测到其中一个共享页面上的写入,它会禁用该页面的共享,创建它的独立副本并让程序写入那里。

此技巧在数据很有可能不会更改但可能发生的情况下特别有用。

可以使用此技术的另一种情况是当一个进程分叉时:新进程不是复制每个内存页面(如果子进程立即执行 a 则完全没用exec),新进程与父进程共享其所有内存页面在写入时复制模式,允许快速创建进程,仍然“伪造”“经典”分叉行为。

于 2011-07-15T13:04:29.950 回答
2

如果一个物理地址(例如,shell 程序)映射到两个独立的虚拟地址

可以构建多个进程共享一块内存;例如,一个充当写入内存的服务器,另一个充当读取内存的客户端,或者同时读取和写入。这是进行进程间通信 (IPC) 的一种非常快速的方式。(其他解决方案,例如管道和套接字,需要将数据复制到内核,然后复制到共享内存跳过的其他进程。)但是,与任何 IPC 解决方案一样,程序必须协调它们对共享内存区域的读取和写入通过一些消息传递协议。

此外,示例中的“系统中运行bash命令 shell 的多个进程”将共享其地址空间的只读部分,其中包括代码。他们可以同时执行相同的内存代码,并且不会互相杀死,因为他们不能修改它。

在报价单中

一般来说,一个特定的物理页面只映射到一个应用程序的虚拟空间

“一般”部分实际上应该是“通常”:除非您将它们设置为,否则不会共享内存页面,或者除非它们是只读的。

于 2011-07-15T12:56:17.247 回答