我有一个共享库(.so),我在执行应用程序之前预加载,并且在应用程序使用的共享库中有一些全局数据结构。应用程序可以使用fork()创建其他进程,并且这些进程可以更新共享库中的全局数据结构。我希望对所有流程中的这些全球数据结构保持一致的看法。有什么办法可以在Linux中完成这个任务吗?如何在共享库(.so)中的共享库中使用共享库的相同进程的实例共享全局变量?
我曾尝试使用shm_ *调用和mmap()将共享库的全局数据映射到共享段,但它不起作用。
我有一个共享库(.so),我在执行应用程序之前预加载,并且在应用程序使用的共享库中有一些全局数据结构。应用程序可以使用fork()创建其他进程,并且这些进程可以更新共享库中的全局数据结构。我希望对所有流程中的这些全球数据结构保持一致的看法。有什么办法可以在Linux中完成这个任务吗?如何在共享库(.so)中的共享库中使用共享库的相同进程的实例共享全局变量?
我曾尝试使用shm_ *调用和mmap()将共享库的全局数据映射到共享段,但它不起作用。
如何在已知的目录位置创建一个简单的管道,然后让其他进程打开分别读/写la fread/fwrite的管道以共享数据......棘手的部分是确保数据是在这种情况下,通过管道不会导致腐败。上面提到的使用共享内存shm_和mmap的过程与fork过程有关,当你fork代码时,这是没有问题的,因为fork代码是原始过程的一部分!希望这可以帮助。
最好的问候, 汤姆。
要最清楚地表达这一点:你不能完全按照你的要求去做。 Linux不支持链接器分配的全局变量。该内存将处于不可映射的交换空间。
一般的食谱,我可以提供的是:
如果你真的只关心一个父母,并且它是分叉的孩子,你可以使用匿名映射而不用打扰文件,并且可以将映射的位置存储在全局中(可以读入这些孩子)。
如果您只想与后代进程共享数据(而不是与独立启动的任意进程共享,那么恰好链接到相同的共享库),那么最简单的方法是该库在构造函数中创建与mmap()
的映射(在库最初在父进程中加载时调用该映射)。
将MAP_ANONYMOUS
和MAP_SHARED
标志传递给mmap
- 这将意味着继承映射的子进程将具有与父级(和其他子级)共享的映射。然后,库应该存储数据结构以便在mmaped内存段中共享(就像它是从malloc
返回的内存一样)。显然你可能需要某种锁定。
库的构造函数可以使用gcc
__constructor__
函数属性来指示。
您不必担心清理这种共享内存 - 当最后一个使用匿名映射的进程退出时,内存将被清理。
这不符合OP的要求:双向共享全局变量。 – bmargulies 2009-11-23 00:28:55
当然,如果这些全局变量存储在共享映射中(这可能意味着全局变量实际上需要指针,但这只是一个实现细节)。 – caf 2009-11-23 02:03:11
它会跨fork()而不是exec()(说新进程使用相同的库),所以在通常情况下不起作用 – MarkR 2009-11-23 13:24:58