我似乎无法找到一个答案后,在网上搜索出来。dlopen是否创建多个库实例?
当我使用dlopen的第一次它似乎需要更长的时间比之后的任何时间,包括如果我从程序的多个实例运行。
dlopen的是否加载了所谓到内存中一次,并有OS保存它,这样即使是从程序点的另一个实例在内存中的相同点以下的任何电话?
所以基本上不会运行库的程序的3个实例意思是相同的。所以3个实例被加载到内存中,还是有只有一个实例在内存中?
感谢
我似乎无法找到一个答案后,在网上搜索出来。dlopen是否创建多个库实例?
当我使用dlopen的第一次它似乎需要更长的时间比之后的任何时间,包括如果我从程序的多个实例运行。
dlopen的是否加载了所谓到内存中一次,并有OS保存它,这样即使是从程序点的另一个实例在内存中的相同点以下的任何电话?
所以基本上不会运行库的程序的3个实例意思是相同的。所以3个实例被加载到内存中,还是有只有一个实例在内存中?
感谢
dlopen的是否加载了所谓到内存中一次并且操作系统将其保存,这样即使是从程序点的另一个实例在内存中的相同点以下的任何电话?
保证多次调用dlopen
从一个进程内多次不加载库。从man page:
If the same shared object is loaded again with dlopen(), the same
object handle is returned. The dynamic linker maintains reference
counts for object handles, so a dynamically loaded shared object is
not deallocated until dlclose() has been called on it as many times
as dlopen() has succeeded on it.
何时dlopen
第一次调用发生时,该库是mmap
版到调用进程。通常至少有两个独立的mmap
调用:.text
和.rodata
部分(通常驻留在单个RO段中)映射为只读,.data
和.bss
部分映射为可读写。
从另一个过程中的后续dlopen
执行相同mmap
秒。然而,操作系统不需要从磁盘加载任何只读数据 - 它只是增加已经加载的第一个dlopen
调用页面上的引用计数。这就是共享“共享库”。
因此,基本上运行库的程序的3个实例是指3个相同的实例.so被加载到内存中,还是在内存中只有一个实例?
取决于你所说的“实例”。每个进程都有自己的一组(动态分配的)运行时加载器结构来描述这个库,并且每个进程将包含共享库的“实例”(可以在不同进程的不同地址加载)。每个进程也将拥有自己的可写数据实例(使用写时复制语义)。但只读映射将全部占用相同的物理内存(尽管它们可能出现在每个进程的不同地址中)。
谢谢你的详细解答。 – Questionable
它不叫白白共享库。 –
太棒了!我知道它是共享的,所以其他程序可以调用它。我有一个强大但未经证实的怀疑,即操作系统足够聪明,只能将其记忆一次。感谢您及时的回复。 – Questionable
在我看来,这可能取决于操作系统的实现,但理论上dlopen应该在打开时mmap lib及其所有依赖项。然后在逻辑上听起来是为了重用原因在进程之间共享映射的内存。我想这种过程可能会以某种方式解释你所观察到的。但请记住,您的计时可能是由其他原因造成的,例如文件系统缓存或扫描。其他。 – dmi