关闭和取消映射POSIX共享内存对象

时间:2017-05-05 16:23:28

标签: c posix shared-memory

我目前正在使用POSIX命名信号量和共享内存,我从手册页中读到所有打开的命名信号量在进程终止时自动关闭。这也是共享内存对象的情况,它们是否也已关闭和取消映射,或者只是关闭?我在手册页上找不到任何相关信息。

2 个答案:

答案 0 :(得分:2)

  

共享内存对象也是如此,它们是否也已关闭   并取消映射或只是关闭?

它们是未映射的,但如果它们没有明确取消链接,它们可能会继续占用后备文件系统中的空间(通常是内存上的/ dev / shm的tmpfs / shmfs)。

在FreeBSD上,可以使用非便携式SHM_ANON标志自动取消链接。如果你想要这种行为,你可以:

  1. 使用带有MAP_ANONYMOUS标志的mmap(2)并通过fork(2)共享文件描述符,或使用Unix域套接字将它们发送到sendmsg(2)的其他进程。
  2. 将System V共享内存与IPC_RMID标志一起使用,该标志会在最后一个进程分离后自动销毁内存段。当进程死亡或调用shmdt(2)时会发生拆卸。
  3. 使用较新的仅限Linux的memfd_create(2)系统调用。

答案 1 :(得分:1)

问题似乎是关于如何以及何时清理一个或多个进程使用的POSIX共享内存,或者可能是关于如何避免过早清理共享内存。

POSIX共享内存是在有意类似于常规文件访问的模型上设计的。特别是,

  • shm_open()将创建并打开一个新的持久共享内存对象,或者只是打开一个现有的共享内存对象,具体取决于是否已有一个具有指定名称的对象。
  • 该区域可以由其他进程打开(因此必须保留),直到通过shm_unlink()取消关联。
  • 共享内存区域在取消链接后仍然存在,只要任何进程打开它,但无法再通过shm_open()打开它。
  • 通过mmap()映射共享内存区域具有在映射到位时保持打开的效果,与用于映射它的文件描述符无关

此外,共享内存区域的内存映射在大多数方面与常规文件的映射相同。映射是按进程属性;它们不会在它们所属的过程终止后继续存在。映射在fork()之间保留(重复)。

在某些系统上,甚至可以通过文件系统访问共享内存区域。除了管理它们的不同功能之外,它们与常规文件最显着的区别可能是它们不会在重新启动后持续存在。

因此,您无需担心终止某个进程会不必要地拆除其他进程正在使用的共享内存区域。另一方面,您可以通过在需要按名称获取访问权限的每个进程完成后取消链接来自动清理共享内存区域。如果您打算仅授予对子进程(以及他们的子进程等)的访问权限,那么您可以在创建后立即取消链接。孩子们在分叉时会继承映射。

所以,回答实际问题:

  

共享内存对象也是如此,它们是否也已关闭和取消映射,或者只是关闭?

当进程终止时,进程打开和/或映射的共享内存对象都会关闭和取消映射,但它们不会自动取消链接。它们将持续至少直到手动取消链接或系统重新启动。