我编写了一个连续运行的服务器(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 的手册页一致,并且适用于我的服务器/工作人员案例。
但是,现在我希望工作人员能够在彼此之间共享某些数据,并且可能(用于测试)在服务器未运行时执行此操作。
如果我在一个工作程序中创建一个共享内存对象,并且在退出时不使用 munmap(...) 和 shm_unlink(...),我注意到共享内存对象保留在 /dev/shm 中,并且我可以打开在另一个工作程序中再次执行此操作。这很方便。
然而,这样做安全吗? (即重复运行映射共享内存的程序,然后不会取消映射/取消链接它)?我猜 unmap() 并不重要,因为内存映射会随着进程而消失,但是 shm_unlink 呢?鉴于操作系统根据对象是否仍在使用来决定何时删除该对象,如果我每次都无法调用 shm_unlink() ,这是否会导致某种泄漏?
唯一的漏洞是,即使在最后一个打开该文件的进程存在之后,该文件仍将保留。
但由于这就是本案的意图,因此它并不是真正的泄漏。
文件在/dev/shm
行为就像普通文件一样(因为它们就是)。
这意味着可以删除该名称(使用unlink
or shm_unlink
)但文件数据将保留,直到名称消失并且使用它的最后一个进程停止这样做(打开文件或其内容mmap
:ed 算作使用它)。
但无论您打开和/或映射它多少次,都只有一个文件。
当进程退出时,所有打开的文件描述符都将关闭,并且所有内存映射都将被删除。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)