在取消链接和替换之前可以更改共享内存吗?

时间:2014-10-14 17:44:06

标签: c shared-memory

我有一个场景,其中进程A打开并写入一些共享内存段" foo"并且进程B打开并读取(仅读取)此内存。每当重新启动A时,它会清除共享内存文件(这是为了防止过时的文件存档,以及B错误地打开过时文件)。

问题是,如果我重新启动A,我基本上会使共享内存无效" foo" B正在使用并需要重新启动B.我想解决这个问题如下:

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

我担心的是,如果我shm_unlink(" foo")并重新创建它,那么B可能不再依赖陈旧的" foo&#34 ;甚至阅读有效性标志!这种做法是否以这种方式不安全?

1 个答案:

答案 0 :(得分:2)

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

当映射的最后一个进程通过调用munmap()取消映射,并且已关闭(通过调用close())shm_open返回的描述符时,将删除该内容。 (通常情况下,描述符应该在mmap()之后关闭)

所以进程B中的原始内存段在进程A之后被称为shm_unlink是有效的,并且当进程B munmap()时它将被销毁,如果进程B是最后一个进程,那么另一个shm_open()将会为您提供创建过程A的新段。

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