8

如果该库被多个进程使用,是否可以将位于共享库 (.so) 中的全局变量用作单例?

例如初始值为 0,进程 1 递增 var 然后 proc2 递增 val 并打印它。

到目前为止,我的实验表明,这两个进程都保留了变量的副本,如果第一个增加它,第二个仍然会读取 0。所以行为不像 Windows DLL...

我在这里的一篇文章中读到,如果全局变量不是静态的(在 lib 中)并且它在 lib 标头中声明为 extern,则 var 对于所有进程都是唯一的。但到目前为止,我还没有能够做到这一点 - var 仍然是每个进程的副本。

有人可以对此提供很好的解释吗?以及如何做到这一点...

4

3 回答 3

7

如果一个共享库(或 Windows DLL)被多个进程使用,任何可修改的数据仍然是进程私有的。有像写时复制这样的机制,只要它只被读取,相同的数据就会被共享,但只要它被任一进程写入就会被复制。因此,对于每个流程,有效的数据仍然是独立的。另请参见共享库地址空间

如果要在进程之间共享数据,则需要使用共享内存,并确保进程之间对共享内存的访问是同步的。

于 2013-01-28T13:32:18.903 回答
1

每个进程都存在于自己的内存空间中。(想象一下,如果可以的话,您可能会对机器造成严重破坏,只需加载某个其他进程正在使用的库,就可以完全随意地破坏它们的地址空间!)因此,全局变量是全局的,但仅在进程内。

于 2013-01-28T13:35:26.977 回答
1

Linux 不支持共享链接器布局的全局变量。该内存将位于不可共享的空间中。

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

MAP_ANONYMOUS将andMAP_SHARED标志传递给mmap- 这意味着继承映射的子进程将具有与父进程(和其他子进程)共享的映射

于 2013-01-28T13:44:07.117 回答