如何在Linux中使用共享库的同一进程的实例之间共享共享库(.so)中的全局变量?

时间:2009-11-22 23:55:22

标签: linux shared-libraries

我有一个共享库(.so),我在执行应用程序之前预先加载,并且在应用程序使用的共享库中有一些全局数据结构。应用程序可以使用fork()创建其他进程,这些进程可以更新共享库中的全局数据结构。我希望在所有流程中保持对这些全局数据结构的一致看法。有什么方法可以在Linux中实现这个目标吗?

我尝试使用shm_ *调用和mmap()将共享库的全局数据映射到共享段但不起作用。

3 个答案:

答案 0 :(得分:8)

最清楚地说明这一点:你不能完全按照你的要求做。 Linux不支持共享链接器列出的全局变量。该内存将处于不可共享的映射到交换空间。

我能提供的一般食谱是:

  1. 定义一个用于布置数据的结构。没有指针!只是抵消。
  2. 第一个进程在/ tmp中创建一个文件,根据需要设置访问权限。使用MAP_SHARED打开,mmap。
  3. 后续流程也会打开,mmap与MAP_SHARED。
  4. 每个人都使用结构来查找他们引用,读取或写入的部分。
  5. 注意并发!
  6. 如果你真的只关心父母和它的分叉孩子,你可以使用匿名映射而不打扰文件,你可以将映射的位置存储在全局(可以在子节点中读取)

答案 1 :(得分:4)

如果您只想与后代进程共享数据(而不是与单独启动的任意进程共享,那恰好恰好链接到同一个共享库),那么最简单的方法是使用library在构造函数中创建一个带mmap()的映射(在最初在父进程中加载​​库时调用)。

MAP_ANONYMOUSMAP_SHARED标志传递给mmap - 这意味着继承映射的子进程将具有与父级(以及其他子级)共享的映射。然后,库应存储要在该mmaped内存段中共享的数据结构(就像它是从malloc返回的内存一样)。显然你可能需要某种锁定。

可以使用gcc __constructor__函数属性指示库的构造函数。

您无需担心清理此类共享内存 - 当使用匿名映射的最后一个进程退出时,内存将被清除。

答案 2 :(得分:0)

如何在已知目录位置创建一个简单的管道,然后让其他进程分别打开管道来读取/写入la fread / fwrite,以共享数据......棘手的部分是确保数据通过在这种情况下,通过管道不会导致腐败。上面你提到的使用共享内存shm_和mmap绑定到进程,当你fork代码时,这没问题,因为fork'd代码是原始进程的一部分!希望这会有所帮助。

祝你好运, 汤姆。