C++ dlopen是否创建多个库实例?
在网上搜索后,我似乎找不到答案 当我第一次使用dlopen时,它似乎比之后的任何时间都要长,包括从一个程序的多个实例运行它 dlopen是否将so加载到内存中一次,并让操作系统保存它,以便任何后续调用(即使来自程序的另一个实例)都指向内存中的同一位置 那么,一个运行库的程序的3个实例基本上意味着3个相同的实例。那么,它们被加载到内存中,还是内存中只有一个实例 谢谢 dlopen是否将so加载到内存中一次,并让操作系统保存它,以便任何后续调用(即使来自程序的另一个实例)都指向内存中的同一位置 在单个进程中多次调用C++ dlopen是否创建多个库实例?,c++,shared-libraries,dlopen,C++,Shared Libraries,Dlopen,在网上搜索后,我似乎找不到答案 当我第一次使用dlopen时,它似乎比之后的任何时间都要长,包括从一个程序的多个实例运行它 dlopen是否将so加载到内存中一次,并让操作系统保存它,以便任何后续调用(即使来自程序的另一个实例)都指向内存中的同一位置 那么,一个运行库的程序的3个实例基本上意味着3个相同的实例。那么,它们被加载到内存中,还是内存中只有一个实例 谢谢 dlopen是否将so加载到内存中一次,并让操作系统保存它,以便任何后续调用(即使来自程序的另一个实例)都指向内存中的同一位置 在单
dlopen
,保证不会多次加载库。从:
当第一次调用dlopen
时,库被mmap
插入调用过程。通常至少有两个独立的mmap
调用:.text
和.rodata
节(通常位于单个RO段中)以只读方式映射,而.data
和节以读写方式映射
来自另一个进程的后续dlopen
执行相同的mmap
s。但是,操作系统不必从磁盘加载任何只读数据——它只会增加第一次dlopen
调用已加载页面上的引用计数。这就是“共享库”中的共享
那么,一个运行库的程序的3个实例基本上意味着3个相同的实例。那么,它们被加载到内存中,还是内存中只有一个实例
取决于您所称的“实例”
每个进程都有自己的一组(动态分配的)运行时加载器结构来描述这个库,每个集合都包含一个共享库的“实例”(可以在不同进程的不同地址加载)。每个进程还将拥有自己的可写数据实例(使用写时复制语义)。但只读映射都将占用相同的物理内存(尽管它们可能出现在每个进程的不同地址)
dlopen是否将so加载到内存中一次,并让操作系统保存它,以便任何后续调用(即使来自程序的另一个实例)都指向内存中的同一位置
在单个进程中多次调用dlopen
,保证不会多次加载库。从:
当第一次调用dlopen
时,库被mmap
插入调用过程。通常至少有两个独立的mmap
调用:.text
和.rodata
节(通常位于单个RO段中)以只读方式映射,而.data
和节以读写方式映射
来自另一个进程的后续dlopen
执行相同的mmap
s。但是,操作系统不必从磁盘加载任何只读数据——它只会增加第一次dlopen
调用已加载页面上的引用计数。这就是“共享库”中的共享
那么,一个运行库的程序的3个实例基本上意味着3个相同的实例。那么,它们被加载到内存中,还是内存中只有一个实例
取决于您所称的“实例”
每个进程都有自己的一组(动态分配的)运行时加载器结构来描述这个库,每个集合都包含一个共享库的“实例”(可以在不同进程的不同地址加载)。每个进程还将拥有自己的可写数据实例(使用写时复制语义)。但是只读映射都将占用相同的物理内存(尽管它们可能出现在每个进程中的不同地址)。这不是免费的共享库。太棒了!我知道它是共享的,所以其他程序可以调用它。我有一种强烈但未经证实的怀疑,即操作系统足够聪明,只能将其存入内存一次。感谢您的快速响应。在我看来,这可能取决于操作系统的实现,但理论上,dlopen应该在打开时映射lib及其所有依赖项。然后,出于重用的原因,在进程之间共享映射的内存听起来是合乎逻辑的。我想这种过程可以解释你所观察到的。但也要记住,您的计时可能是由其他原因造成的,如文件系统缓存或smth。还有。它不是免费的共享库。太棒了!我知道它是共享的,所以其他程序可以调用它。我有一种强烈但未经证实的怀疑,即操作系统足够聪明,只能将其存入内存一次。感谢您的快速响应。在我看来,这可能取决于操作系统的实现,但理论上,dlopen应该在打开时映射lib及其所有依赖项。然后,出于重用的原因,在进程之间共享映射的内存听起来是合乎逻辑的。我想这种过程可以解释你所观察到的。但也要记住,您的计时可能是由其他原因造成的,如文件系统缓存或smth。谢谢你的详细回答。谢谢你的详细回答。
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.