在Linux中, 我有一个名为foo.so的共享库文件 当我执行2个不同的进程p1,p2都使用foo.so. 这个foo.so会被这两个进程重叠吗?
答案 0 :(得分:35)
在基于Unix的系统(包括Linux)上,code segment (.text)可以在多个进程之间共享,因为它是不可变的。你提到这个重叠吗?
基本上,每个包含静态数据的共享库(例如全局变量)都有Global Offset Table (GOT)。在共享库上,所有对静态数据的引用(想想全局变量)都是通过GOT(它们是间接的)发生的。因此,即使代码段在多个进程之间共享,每个进程也会对共享库的其他段进行独占映射,包括相应的GOT,其条目也会相应地重新定位。
简而言之,仅在流程之间共享代码,而不是数据。但是,我认为常量可能是一个例外,具体取决于编译标志。
我还建议您阅读以下书籍中的第10章动态链接和加载:Linkers and Loaders。
答案 1 :(得分:5)
操作系统将共享库的代码复制(或更准确地,映射)到内存中。
然后,操作系统会让每个进程访问内存中的那个副本。
每个进程可能会“看到”副本与另一个进程的内存地址不同。这由CPU的内存管理单元解决。
它可能比这更复杂,但这基本上是在Linux和其他与Unix相关的操作系统(如Mac OS X)中的工作原理。
答案 2 :(得分:1)
这两个进程使用共享库代码段的相同物理地址,但是它们的虚拟地址对于这两个进程来说是不同的。虚拟内存有助于在此处实现此功能。
根据 Computer Systems: A Programmer's Perspective 一书,第 9.5 章 VM 作为内存管理工具
<块引用>然而,在某些情况下,进程共享代码和数据是可取的。例如,每个进程必须调用相同的操作系统内核代码,每个 C 程序都调用标准 C 库中的例程,如 printf。与在每个进程中包含内核和标准 C 库的单独副本不同,操作系统可以通过将不同进程中的适当虚拟页面映射到相同物理页面来安排多个进程共享此代码的单个副本。