shm_open()
我的问题是关于初始化使用and获得的内存mmap()
。我在几个地方看到的一个常见建议是shm_open()
使用标志调用O_CREAT|O_EXCL
:如果成功,那么我们是共享内存的第一个用户并且可以初始化它,否则我们不是第一个并且共享内存已经被另一个进程初始化.
但是,根据我shm_open
对 Linux 的理解和测试,这是行不通的:共享内存对象会留在系统中,即使在共享内存对象的最后一个用户取消映射并关闭之后也是如此。一个简单的测试程序,它调用shm_open
,O_CREAT|O_EXCL
然后关闭描述符并退出,将在第一次运行时成功,但在第二次运行时仍然会失败,即使当时没有其他人正在使用共享内存。
在我看来,(至少在我测试的系统上)的行为shm_open
几乎与以下内容相同open()
:如果我修改我的简单测试程序以将某些内容写入共享内存(通过 获得的指针mmap
)并退出,那么共享内存对象将永久保留其内容(我可以运行另一个简单的程序来读回我之前编写的数据)。
那么关于使用shm_open
with的建议O_CREAT|O_EXCL
是错误的,还是我错过了什么?
我确实知道可以使用 删除共享内存对象shm_unlink()
,但似乎只会导致更多问题:
如果一个进程在调用之前就死掉了,
shm_unlink()
那么我们又回到了上面描述的问题。如果一个进程调用
shm_unlink()
,而其他一些进程仍然映射到同一个共享内存,这些其他进程仍将继续照常使用它。现在,如果另一个进程来并shm_open()
以相同的名称和O_CREAT
指定的调用,它实际上将成功创建具有相同名称的新共享内存对象,这与其他进程仍在使用的旧共享内存对象完全无关。现在我们有一个进程试图通过共享内存与其他进程通信,并且完全不知道它使用了错误的通道。
我习惯于 Windows 语义,其中共享内存对象仅在至少有一个句柄对其开放时才存在,所以这个 Posix 的东西非常令人困惑。