c++ - 单个进程如何处理链接到同一库的多个共享库?

标签 c++ c linux shared-libraries static-libraries

多个共享库链接到单个进程中的同一库。

假设我有 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.2libpcre.so.3 一起加载。 这是解决 ABI 不兼容性的一种方法。

关于c++ - 单个进程如何处理链接到同一库的多个共享库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76389490/

相关文章:

c++ - 在 C++ 中的循环中正确删除动态分配的对象的位置

c++ - 如何将 find_if 与链表等非容器一起使用?

将float转换为c中的字符串

c - 指针值在函数调用过程中发生变化

linux - 使用 Qt 在 Linux 中触摸事件

linux - rsyslog "if"语句不起作用

c++ - 升级到SQL Server 2005 : Cannot INSERT QNAN into float column?

c++ - 测试和自定义构建目录的组合

c - 验证表达式 getchar() != EOF 是 0 或 1,ctrl-D 得到 "0D",而不是 "0"

linux - 不同的Python在不同的SSH登录中表现如何?