【问题标题】:How can I share library between two program in c如何在c中的两个程序之间共享库
【发布时间】:2014-02-22 17:12:26
【问题描述】:

我想在 C 中的两个不同程序中使用相同的库函数(即 OpenSSL 库)进行计算。如何确保两个程序都使用一个公共库,这意味着 只有 一个库副本被加载到 共享主内存 并且两个程序都从该内存位置访问该库计算?

例如,当第一个程序访问库进行计算时,它从主内存加载到缓存中,当第二个程序想要稍后访问它时,它将访问缓存中的数据(已经被第一个程序加载),不是再次从主内存中。

我在 Linux 下使用 GCC。任何解释或指针将不胜感激。

【问题讨论】:

  • 使用共享库。之后操作系统会处理其余的事情。
  • 你说的是代码段还是数据段?我想代码段是每个共享对象,数据段是每个进程。
  • @adrin,我想在不同的程序中对不同的数据集进行相同的计算,但使用相同的库。
  • 这就是共享库的用途。

标签: c linux operating-system shared-libraries cpu-cache


【解决方案1】:

阅读 Drepper 的论文 How to Write Shared LibrariesProgram Library HowTo

要制作一个,请将您的代码编译为position independent code,例如

 gcc -c -fPIC -O -Wall src1.c -o src1.pic.o
 gcc -c -fPIC -O -Wall src2.c -o src2.pic.o

然后将其链接到共享对象中

 gcc -shared src1.pic.o src2.pic.o -lsome -o libfoo.so

您可以将共享库 -lsome 链接到另一个共享库 libfoo.so

在内部,动态链接器ld-linux.so(8) 正在使用mmap(2)(并且会在动态链接时执行一些relocation),重要的是inodes。内核将使用文件系统缓存来避免两次读取不同进程使用的共享库。另见linuxatemyram.com

使用例如ldd(1)pmap(1)proc(5)。另见dlopen(3)。试试

cat /proc/self/maps

了解运行cat 命令的process 使用的virtual memoryaddress space;并非ELF 共享库的所有内容都在进程之间共享,只有一些段,包括text segment...

【讨论】:

    【解决方案2】:

    代码被操作系统共享,不仅是共享库,还包括同一二进制文件的可执行文件——你不需要做任何事情来拥有这个特性。它是系统内存管理的一部分。

    数据不会在两个进程之间共享。您需要一个进程中的线程来共享数据。但除非你愿意,否则只要确保两个程序都使用完全相同的共享库文件(.so 文件)。通常您不必考虑这一点。仅当两个程序使用库的不同版本时才重要(它们当然不会被共享)。

    查看ldd /path/to/binary 的输出,了解二进制文件使用了哪些共享库。

    【讨论】:

    • ldd 这不是 100% 可靠的,你需要知道 ldd 做了什么才能解释它自己的输出。 ldd 也受其运行环境的影响,而该环境可能与您的应用运行的环境完全不同。
    • 当然。我没有想到 OP 可能会尝试使用 不同的计算机 来找出他的二进制文件将使用哪个共享库。在我的回答中提到这一点有意义吗?使用不同的机器似乎很牵强,我认为在这里的 cmets 中考虑这一点就足够了。
    • 一个不同的环境它不是一个不同的计算机,如果你这样写,我想你不知道ldd 的作用;这真的不是重点。
    • 我发现在答案中写下对ldd 的调用应该在也会发生执行的环境中完成(同一台计算机、同一用户、相同配置)太明显了。我不明白您的反对意见在哪些方面不同于指出使用lsdu 或类似的Unix 工具取决于很多事情,并且在不同情况下可能会产生不同的结果。嗯,当然可以。陈述显而易见的事实不会使答案变得更好。但由于未来的读者可能不会注意到这一点,我觉得可以在评论中说明这一点。
    猜你喜欢
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    相关资源
    最近更新 更多