【问题标题】:C Linux: Global variable located in shared library as singletonC Linux:位于共享库中的全局变量作为单例
【发布时间】:2013-01-28 13:19:57
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 每个进程的数据都是私有的 - Windows DLL 有何不同?我想你想要的是Shared Memory 在进程之间共享数据,对吧?
  • 有人告诉我,Win DLL 不是这种情况,但我想这不是真的...我想要一个单例,但不知道该怎么做...我有 2进程和 1 个库。
  • “单例”通常意味着每个进程一个实例。
  • 好的,所以按照下面的 cmets 我需要 SharedMemory。是否可以从 Lib 中创建这样的内存,然后在每个使用该 lib 的进程中使用它?

标签: c linux shared-libraries


【解决方案1】:

如果一个共享库(或 Windows DLL)被多个进程使用,任何可修改的数据仍然是进程私有的。有像 Copy on Write 这样的机制,其中只要读取相同的数据就会被共享,但一旦被任一进程写入就会被复制。因此,对于每个流程,有效的数据仍然是独立的。另见shared library address space

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

      • 您的意思是在 LIB 中使用 shm_open() 和 mmap() 进行初始化,然后从使用 LIB 的每个进程执行相同操作 - shm_open+mmap 使用空间?
      • 您可以在后代进程之间共享数据,而不是在任意进程之间
      • 这里有点困惑:(我指的是这个例子:codemaestro.com/reviews/11 lib 创建共享内存,然后每个进程都可以访问同一个文件。对不起......我n00b......跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多