【问题标题】:Is it ok to alter shared memory before unlinking and replacing it?在取消链接和替换之前可以更改共享内存吗?
【发布时间】:2014-10-14 17:44:06
【问题描述】:

我有一个场景,其中进程 A 打开并写入一些共享内存段“foo”,而进程 B 打开并读取(仅读取)该内存。每当 A 重新启动时,它都会清除共享内存文件(这是为了防止陈旧的文件滞留并防止 B 错误地打开一个陈旧的文件)。

问题是,如果我重新启动A,我基本上会使B正在使用的共享内存“foo”失效,需要重新启动B。我想通过以下方式解决这个问题:

每当 A 启动时,它都会查找“foo”,但在调用 shm_unlink(“foo”) 之前,它会向“foo”中的标头写入一些内容 - 一些标志 - 这表示它不再有效。然后它调用 shm_unlink("foo") 然后通过 shm_open 和 O_CREAT 重新创建它。 B 在尝试依赖 mem_mapped "foo" 的内容之前会检查这个标志,如果它发现标志无效,它会重新加载(即等待几秒钟,然后再次在文件系统中搜索 "foo" 并内存映射它)。

不过,我担心的是,如果我 shm_unlink("foo") 并重新创建它,那么 B 可能不再依靠陈旧的 "foo" 来读取有效性标志!这样的做法不安全吗?

【问题讨论】:

    标签: c shared-memory


    【解决方案1】:

    不,没关系。共享内存段是引用计数的。当您调用 shm_unlink() 时,您只是删除了段的名称,而不是内容。

    当最后一个映射它的进程通过调用 munmap() 取消映射并关闭(通过调用 close())由 shm_open 返回的描述符时,内容被删除。 (通常描述符应该在被 mmap() 编辑后关闭)

    因此,进程 B 中的原始内存段在进程 A 调用 shm_unlink 后有效,并且如果进程 B 是最后一个执行此操作的进程,则在进程 B munmap() 时将其销毁,并且执行另一个 shm_open() 将给你进程 A 创建的新段。

    请务必处理竞争条件,如果进程 A 未完成旧段,您的进程 B 可能会再次打开旧段,或者您可能会在进程 A 再次创建或初始化之前尝试打开该段。

    【讨论】:

    • 我们不应该在 processA 和 processB 之间使用同步来确保 B 没有读取部分更新的内存吗?还是真正的共享内存操作原子?
    • @SergeBallesta 你当然需要同步访问共享内存。
    猜你喜欢
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    相关资源
    最近更新 更多