我不太明白“多个独立虚拟地址,指向相同的物理地址”的好处,即使我阅读了很多书籍和帖子,
,类似的问题Difference between physical addressing and virtual addressing concept,
帖子声称程序不会相互崩溃,
“通常,特定的物理页面只映射到一个应用程序 虚拟空间“
嗯,在http://tldp.org/LDP/tlk/mm/memory.html中,在“共享虚拟内存”一节中,它说
“例如,系统中可能有多个进程在运行 bash命令shell。一个,而不是有几个bash的副本 在每个进程虚拟地址空间中,最好只有一个 复制物理内存和运行bash共享的所有进程 它“。
如果一个物理地址(例如,shell程序)映射到两个独立的虚拟地址,那怎么能不崩溃?它与使用物理寻址不一样吗?
虚拟寻址提供什么,这是物理寻址不可能或不方便的?如果不存在虚拟内存,即两个直接指向同一物理内存?我认为,通过使用一些协调机制,它仍然可以工作。那么为什么要打扰“虚拟寻址,MMU,虚拟内存”呢?
答案 0 :(得分:4)
此功能有两个主要用途。
首先,您可以在进程之间共享内存,可以通过共享页面进行通信。事实上,共享内存是IPC最简单的形式之一。
但共享只读页面也可用于避免无用的复制:大多数情况下,程序代码在加载到内存后不会改变,因此其内存页面可以在运行的所有进程之间共享那个节目。显然只有代码是共享的,包含堆栈,堆的内存页面以及一般程序中的数据(或者,如果您愿意,状态)不会被共享。
这个技巧通过“写入时复制”得到改善。可执行文件的代码通常在运行时不会改变,但是有些程序实际上是自我修改的(过去很常见,当大部分开发仍然在程序集中完成时);为了支持这些东西,操作系统执行如前所述的只读共享,但是,如果它检测到其中一个共享页面上的写入,则会禁用此页面的共享,创建它的独立副本并让程序写入那里。
这种技巧在数据不太可能发生变化的情况下特别有用,但可能会发生。
可以使用这种技术的另一种情况是当进程分叉时:而不是复制每个内存页(如果子进程立即执行exec
,则完全无用),新进程与父进程共享所有内存页面都在写入模式下复制,允许快速创建进程,仍然“伪造”“经典”fork行为。
答案 1 :(得分:2)
如果一个物理地址(例如,shell程序)映射到两个独立的虚拟地址
可以构建多个进程来共享一块内存;例如一个作为服务器写入内存,另一个作为客户端读取,或读取和写入。这是进行进程间通信(IPC)的一种非常快速的方法。 (其他解决方案,例如管道和套接字,需要将数据复制到内核,然后再转移到共享内存跳过的其他进程。)但是,与任何IPC解决方案一样,程序必须协调其读取并通过某种消息传递协议写入共享内存区域。
此外,示例中“运行bash
命令shell的系统中的几个进程”将共享其地址空间的只读部分,其中包括代码。它们可以同时执行相同的内存中代码,并且不会相互杀死,因为它们无法修改它。
在报价中
通常,特定物理页面仅映射到一个应用程序的虚拟空间
“一般”部分应该“通常”:内存页面不共享,除非您将它们设置为,或者除非它们是只读的。