我的问题涉及使用
然而,从我对
实际上,在我测试的系统上,
所以,关于使用带有
我知道可以使用
1.如果一个进程在调用
2.如果一个进程调用
我习惯于Windows语义,其中共享内存对象仅存在于至少有一个句柄打开的情况下,因此这个Posix东西非常令人困惑。
shm_open()
和mmap()
初始化内存。在几个地方我看到的一个普遍建议是使用标志O_CREAT|O_EXCL
调用shm_open()
:如果成功,那么我们是共享内存的第一个用户并且可以初始化它,否则我们不是第一个用户并且共享内存已经被另一个进程初始化。然而,从我对
shm_open
的理解以及我在Linux上进行的测试中,这种方法行不通:即使最后一个共享内存对象的用户取消映射并关闭了它,共享内存对象仍会留存在系统中。一个简单的测试程序调用shm_open
与O_CREAT|O_EXCL
,然后关闭描述符并退出,将在第一次运行时成功,但即使此时没有其他人使用共享内存,第二次运行仍将失败。实际上,在我测试的系统上,
shm_open
的行为似乎与open()
基本相同:如果我修改我的简单测试程序通过mmap
获取指针将某些内容写入共享内存,然后退出,那么共享内存对象将持续保留其内容(我可以运行另一个简单程序来读取我之前写入的数据)。所以,关于使用带有
O_CREAT|O_EXCL
标志的shm_open
的建议是否错误,还是我遗漏了什么?我知道可以使用
shm_unlink()
删除共享内存对象,但这似乎只会导致更多问题:1.如果一个进程在调用
shm_unlink()
之前死亡,则我们又回到了上面描述的问题。2.如果一个进程调用
shm_unlink()
,而其他一些进程仍然映射到相同的共享内存中,则这些其他进程仍将像往常一样继续使用它。现在,如果另一个进程来并使用与旧共享内存对象相同的名称和指定了O_CREAT
,它实际上将成功创建具有相同名称的新共享内存对象,该对象与其他进程仍在使用的旧共享内存对象完全无关。现在我们有一个进程试图通过共享内存与其他进程通信,并且完全不知道它正在使用错误的通道。我习惯于Windows语义,其中共享内存对象仅存在于至少有一个句柄打开的情况下,因此这个Posix东西非常令人困惑。
ipcs
命令查看当前在系统中存在哪些IPC内容(信号量、shm段等)。 - Reritoshm_unlink()
是没有理由不这样做的。 - Reritoshm_open()
获取描述符,并在此之后立即使用shm_unlink()
将其删除。然后,您可以通过fork()
共享描述符。 - GreenScape