shm_unlink 的行为

Behaviour of shm_unlink

我有以下代码片段:

fd_mem = shm_open(MEM_NAME , O_RDWR | O_CREAT | O_EXCL , 0600);

//Why do we use unlink before having mmaped ? 
shm_unlink ( MEM_NAME );

ftruncate (fd_mem , mem_size)
    
plateau = (char*) mmap(NULL , mem_size , PROT_READ | PROT_WRITE , MAP_SHARED , fd_mem , 0);

我的问题是:为什么我们在将文件映射到进程的虚拟内存之前使用“unlink”?我对 shm_unlink() 在这方面的工作方式感到困惑。我认为它会删除使 [​​=17=]fd_mem 无法使用的文件,但它不会。

好的,只有在不再引用该文件时才会删除文件,这包括打开的文件描述符,并且由于我们有 fd_mem,shm_unlink 将删除link 在 /dev/shm/MEM_NAME 但在 fd_mem 关闭之前文件不会被删除。

打开文件或共享内存段会增加底层“内核对象”的引用计数器。删除操作,删除对象的名称但不减少引用计数器。只要引用计数器大于 0,对象就不会被销毁。

打开对象后删除对象,是为了在进程自愿终止(退出)或非自愿终止(收到信号)时自动清理:终止触发“关闭”操作,该操作递减引用计数器。当后者降为0时,对象消失,因为删除操作也完成了。

如果没有这个技巧,进程可能会在不进行任何清理的情况下终止,并因此在文件系统中留下“垃圾”条目。

I'm confused as to how shm_unlink works in that regard, I would think it deletes the file rendering fd_mem unusable but it doesn't.

shm_unlink() 删除共享内存段的 name。只要任何进程打开它,段本身就会持续存在,但在取消链接后,进程无法再打开它。即便如此,从持有共享内存段的进程派生出的新进程继承了该段,并且一个进程可以通过 UNIX 域套接字将文件描述符复制到另一个进程,因此取消链接并不会固有地限制哪些进程或多少进程可以访问该段.

这与普通文件和 unlink() 的情况完全相似。成功取消链接文件名会将该名称从其目录中删除,但只要有任何进程打开它,文件本身就不会被删除。

做这种事情的原因有

  • 以确保在进程终止时以任何方式清理资源。只要命名的共享内存段保持链接或进程保持打开状态,它们就会一直存在。通过在创建和打开片段后立即取消链接,一个进程有助于确保它不会比预期的寿命更长,即使该进程崩溃也是如此。

  • 以避免不必要的访问。任何具有足够权限的进程都可以打开命名的共享内存段。取消链接共享内存段有助于控制它。它尤其有助于避免同一程序的多个副本不必要地共享使用。

另请注意,可以创建匿名共享内存段,这些段从一开始就不会链接到名称。这就像创建、打开并立即取消链接的命名段一样,但它不会留下任何 window 其他进程可以按名称意外打开该段的情况。