【问题标题】:Do I need to use shm_unlink on a shared memory object?我需要在共享内存对象上使用 shm_unlink 吗?
【发布时间】:2014-07-10 17:36:07
【问题描述】:

我编写了一个连续运行的服务器(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,即我们假设它已经存在)。

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

此时,有一个文件“/dev/shm/shm_file”,我猜它是共享内存对象。在工作人员中取消链接不会删除它,因为服务器仍然打开它。当服务器取消链接时,文件系统对象就消失了。此行为与 shm_open / shm_unlink 的手册页一致,并且适用于我的服务器/工作人员案例。

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

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

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

【问题讨论】:

    标签: c++ c linux shared-memory


    【解决方案1】:

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

    但由于这是本案的意图,因此并不是真正的泄漏。

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

    这意味着可以删除名称(使用unlinkshm_unlink),但文件数据将保留到名称消失并且使用它的最后一个进程停止这样做(打开文件或其内容@ 987654324@:ed 算使用)。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-14
      • 2012-04-27
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多