我需要在共享内存对象上使用shm_unlink吗?

13

我编写了一个持续运行的服务器(GNU C++ / Linux),偶尔执行一些小型独立程序来完成工作。为了高效地将数据传递给工作程序,服务器创建并映射了一个共享内存对象(代码为了清晰而缩写):

int fd = shm_open("/shm_file", O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
ftruncate(...);
data = mmap(...);
// etc...
launchWorker(...);   // Start the worker program

工作程序以类似的方式打开此共享内存(只读,没有O_CREAT和O_TRUNC,即假设它已经存在)。

当工作者完成时,它关闭文件描述符,使用munmap(...)取消映射,并使用shm_unlink(...)取消链接。

此时,有一个名为“/dev/shm/shm_file”的文件,我猜它是共享内存对象。在工作者中取消链接不会删除它,因为服务器仍然将其打开。 当服务器取消链接时,文件系统对象消失。这个行为与shm_open / shm_unlink的man页面一致,并且对于我的服务器/工作者案例很有效。

然而,现在我希望工作者之间能够共享某些数据,并且可能(用于测试)在服务器未运行时执行此操作。

如果我在一个工作程序中创建共享内存对象,并且在退出时不使用munmap(...)和shm_unlink(...),我注意到共享内存对象仍然存在于/dev/shm中,并且我可以在另一个工作程序中再次打开它。这很方便。

但是,这样做安全吗?(即重复运行映射共享内存的程序,然后不取消映射/取消链接它)?我猜unmap()并不重要,因为内存映射会随着进程消失而消失,但是shm_unlink呢?考虑到操作系统基于是否仍在使用决定何时删除对象,如果我每次都没有调用shm_unlink(),这会导致某种泄漏吗?

1个回答

10

唯一的泄漏是即使打开它的最后一个进程存在之后,文件仍会保留。

但由于在这种情况下这是预期的行为,因此并不真正算作泄漏。

/dev/shm中的文件表现得就像普通文件一样(因为它们就是普通文件)。

这意味着可以删除名称(使用unlinkshm_unlink),但是文件数据将保留,直到名称消失并且最后一个正在使用它的进程停止使用它(拥有打开该文件或其内容被 mmap :ed视为在使用它)。

但只有一个文件,无论您打开和/或 mmap 多少次。

当进程退出时,所有打开的文件描述符都将关闭,并且所有内存映射都将被删除。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接