我编写了一个连续运行的服务器(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
然后,worker程序以类似的方式打开这个共享内存(除了只读,没有O_CREAT和O_TRUNC,即我们假设它已经存在)。
当worker完成时,它会关闭文件描述符,使用munmap(...)取消映射并使用shm_unlink(...)取消链接。
此时,有一个文件“/ dev / shm / shm_file”,我猜是共享内存对象。在工作器中取消链接不会删除它,因为服务器仍然打开它。当服务器取消链接时,文件系统对象消失。此行为与shm_open / shm_unlink的手册页一致,并且适用于我的服务器/工作人员案例。
但是,现在我希望工作人员能够在他们之间共享某些数据,并且可能(用于测试)在服务器未运行时执行此操作。
如果我在一个工作程序中创建一个共享内存对象,并且在它退出时不要使用munmap(...)和shm_unlink(...),我会注意到共享内存对象仍然在/ dev / shm中,并且我可以在另一个工人计划中再次打开它。这很方便。
但是,这样做是否安全? (即重复运行映射共享内存的程序,然后不取消映射/取消链接)?我猜测unmap()并不重要,因为内存映射会随着进程消失,但是shm_unlink呢?鉴于操作系统决定何时根据对象是否仍在使用而删除对象,如果我每次都无法调用shm_unlink(),是否会导致某种泄漏?
答案 0 :(得分:5)
唯一的泄漏是,即使在打开它的最后一个进程存在之后文件也会保留。
但由于这是本案的意图,因此并不是真正的泄密。
/dev/shm
中的文件就像常规文件一样(因为它们都是)。
这意味着可以删除名称(使用unlink
或shm_unlink
),但文件数据将保留,直到名称消失,最后一个使用它的进程停止这样做(打开文件)或者它的内容mmap
:ed计为使用它。)
但是只有一个文件,无论你打开多少次和/或mmap它。
当进程退出时,所有打开的文件描述符都将关闭,并且所有内存映射都将被删除。