2009-11-22 74 views
6

我有一个共享库(.so),我在执行应用程序之前预加载,并且在应用程序使用的共享库中有一些全局数据结构。应用程序可以使用fork()创建其他进程,并且这些进程可以更新共享库中的全局数据结构。我希望对所有流程中的这些全球数据结构保持一致的看法。有什么办法可以在Linux中完成这个任务吗?如何在共享库(.so)中的共享库中使用共享库的相同进程的实例共享全局变量?

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

回答

0

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

最好的问候, 汤姆。

8

要最清楚地表达这一点:你不能完全按照你的要求去做。 Linux不支持链接器分配的全局变量。该内存将处于不可映射的交换空间。

一般的食谱,我可以提供的是:

  1. 定义,规定了您的数据结构。没有指针!只是补偿。
  2. 第一个进程在/ tmp中创建一个文件,根据需要设置访问权限。用MAP_SHARED打开mmap。
  3. 后续进程也会打开,mmap和MAP_SHARED。
  4. 每个人都使用该结构来查找它们引用,读取或写入的部分。
  5. 注意并发!

如果你真的只关心一个父母,并且它是分叉的孩子,你可以使用匿名映射而不用打扰文件,并且可以将映射的位置存储在全局中(可以读入这些孩子)。

4

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

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

库的构造函数可以使用gcc__constructor__函数属性来指示。

您不必担心清理这种共享内存 - 当最后一个使用匿名映射的进程退出时,内存将被清理。

+0

这不符合OP的要求:双向共享全局变量。 – bmargulies 2009-11-23 00:28:55

+0

当然,如果这些全局变量存储在共享映射中(这可能意味着全局变量实际上需要指针,但这只是一个实现细节)。 – caf 2009-11-23 02:03:11

+0

它会跨fork()而不是exec()(说新进程使用相同的库),所以在通常情况下不起作用 – MarkR 2009-11-23 13:24:58