多个共享库链接到单个进程中的同一库。
假设我有 libapp 、 libapp1 、 libapp2 和 Mainapp 。 libapp1 链接到 libapp , libapp2 链接到 libapp.Main 应用程序链接到 libapp1 和 libapp2 。 如果 libapp 中有全局变量,它会有两个拷贝还是一个拷贝? 当 Mainapp 执行时,全局变量的行为是什么?
我看到一个进程只有一份全局变量拷贝,我的理解正确吗? 单个进程的一个定义规则?如果我们有库使用不同的参数调用相同的 api,如何解决这个问题?
最佳答案
在 Linux 上,库依赖项被编码到可执行文件和库中作为 DT_NEEDED 条目。您可以使用 ldd 命令查询:
$ ldd /bin/sed
linux-vdso.so.1 (0x00007ffee2c69000)
libacl.so.1 => /usr/lib/x86_64-linux-gnu/libacl.so.1 (0x00007f0a806c6000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f0a8049e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0a802dd000)
libattr.so.1 => /usr/lib/x86_64-linux-gnu/libattr.so.1 (0x00007f0a802d5000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f0a80261000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f0a8025c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0a806fe000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0a80239000)
每一行都会列出依赖项以及找到该依赖项的实际位置。 默认情况下,动态链接器 (ld.so) 会查询名为/etc/ld.so.conf 的文件以获取要查找的路径列表,但此过程可以通过二进制文件本身(DT_RUNPATH 条目)或环境( LD_LIBRARY_PATH)。有关两者的信息,请参阅 ld.so 联机帮助页。
在 Linux 上,动态链接器确保每个进程仅将特定库文件的单个拷贝加载到内存中。 因此,如果进程中的第二个库具有同一库文件的 DT_NEEDED 条目,它将不会再次加载该文件。
其次,请注意,依赖项不仅称为“libfoo.so”,还称为 libpcre.so.3。这个数字是对库进行版本控制的一种方式。因此,一个进程完全可以将 libpcre.so.2
与 libpcre.so.3
一起加载。
这是解决 ABI 不兼容性的一种方法。
关于c++ - 单个进程如何处理链接到同一库的多个共享库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76389490/