- 论坛徽章:
- 0
|
说说我知道的部分.
每个可执行文件有一个表列出它依赖的DSO(dll 或 so). RTLD(run time link editor)负责把它们装载到进程的内存地址区间.DSO的搜索规则各OS大同小异, 以Solaris为例.
- (1) 缺省路径 /lib and /usr/lib 或 configuration file 所指路径(/var/ld/ld.config 或 环境变量LD_CONFIG)
- (2)可执行文件里runpath所指路径
- (3)环境变量LD_LIBRARY_PATH 所指路径
复制代码
RTLD是根据名称搜索, 一旦找到名称附和的DSO既mapping到进程的内存地址空间. 程序执行时, 需要读该DSO内容, 会产生page fault, 因为只有mapping, VMM(virtual memory management)处理这个page fault, 它会调用vfs(virtual file system)driver把DSO从硬盘copy入内存.
如果有另一个进程有同样DSO的mapping, 而且同样第一次需要读该DSO内容, 也会产生page fault, VMM调用vfs, vfs根据dev/inode发现该文件已在物理内存中, 而且是只读页, 它会重复使用该物理内存页. 最终, 两进程的内存mapping到同样的物理内存.
LZ的问题,
有两个process,都需要用到common.dll,在各个process目录下都有common.dll文件,他们只是内部的实现逻辑有区别,而在导出接口上是一致的,当process 1转载了一个common.dll后,process 2是否会装载另外一个内部逻辑有区别common.dll,而是直接用process 1装载的dll?
process 2是否会用process 1装载的dll, 应当看process 2是否跟process 1有同样的启动环境, 以即是否有一样的runpath.
因为vfs使用dev/inode, 如果相同的DSO存在不同的目录下, 而多个进程因为搜索路径不一样, 相同的DSO可能在物理内存中有多个copy. 当然同一目录下的DSO最多一个copy. 话说回来, 完全相同的DSO就没必要存在不同的目录下. 在开发过程中, 有同样名称的DSO但内容不同, 所以RTLD才有环境变量LD_LIBRARY_PATH |
|