Linux 为什么在shm_unlink()之后fd仍然可用

Linux 为什么在shm_unlink()之后fd仍然可用,linux,system-calls,shared-memory,Linux,System Calls,Shared Memory,我正在阅读中的源代码 作者使用shm_open()创建共享内存,shm_立即取消链接(),然后ftruncate()将fd设置为特定大小,mmap()将fd设置为特定大小,并用像素填充该区域。 我很困惑为什么在shm_unlink()之后fd仍然可用 根据手册页: shm_unlink()的操作类似于unlink(2):它删除共享内存对象名,并且在所有进程取消映射对象后,取消分配并销毁关联内存区域的内容。成功shm_unlink()后,尝试shm_open()打开同名对象将失败(除非指定了O_C

我正在阅读中的源代码

作者使用shm_open()创建共享内存,shm_立即取消链接(),然后ftruncate()将fd设置为特定大小,mmap()将fd设置为特定大小,并用像素填充该区域。 我很困惑为什么在shm_unlink()之后fd仍然可用

根据手册页:

shm_unlink()的操作类似于unlink(2):它删除共享内存对象名,并且在所有进程取消映射对象后,取消分配并销毁关联内存区域的内容。成功shm_unlink()后,尝试shm_open()打开同名对象将失败(除非指定了O_CREAT,在这种情况下,将创建一个新的、不同的对象)

因此shm_unlink()将导致内存被破坏,因为没有进程mmap 该地区。但fd如何仍然有效

代码如下:

static int
create_shm_file(void)
{
    int retries = 100;
    do {
        char name[] = "/wl_shm-XXXXXX";
        randname(name + sizeof(name) - 7);
        --retries;
        int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); 
        if (fd >= 0) {
            shm_unlink(name); // unlink immediately
            return fd;
        }
    } while (retries > 0 && errno == EEXIST);
    return -1;
}

static int
allocate_shm_file(size_t size)
{
    int fd = create_shm_file();
    if (fd < 0)
        return -1;
    int ret;
    do {
        ret = ftruncate(fd, size); //why the fd still available?
    } while (ret < 0 && errno == EINTR);
    if (ret < 0) {
        close(fd);
        return -1;
    }
    return fd;
}
//after above, there was mmap
uint32_t *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

static int
创建\u shm\u文件(无效)
{
int重试次数=100次;
做{
字符名[]=“/wl\U shm-XXXXXX”;
randname(名称+sizeof(名称)-7);
--重试;
int fd=shm|U open(名称,O|RDWR | O|U CREAT | O|U EXCL,S|U IRUSR | S|U IWUSR);
如果(fd>=0){
shm_unlink(name);//立即取消链接
返回fd;
}
}while(重试次数>0&&errno==EEXIST);
返回-1;
}
静态整数
分配\u shm\u文件(大小\u t大小)
{
int fd=create_shm_file();
如果(fd<0)
返回-1;
int ret;
做{
ret=ftruncate(fd,size);//为什么fd仍然可用?
}而(ret<0&&errno==EINTR);
如果(ret<0){
关闭(fd);
返回-1;
}
返回fd;
}
//在上面,有mmap
uint32_t*data=mmap(空、大小、保护读取、保护写入、映射共享、fd、0);

因为
fd
未关闭。它与文件操作一致。文件可以
打开
并在成功
打开
后立即取消链接。返回的
fd
可用于访问文件内容,直到关闭
fd
为止。@NizamMohamed感谢您的评论!我现在明白了,取消链接并不意味着关闭文件,文件仍然存在。这种行为的另一个优点是:您创建/打开任何文件(引用计数器设置为1),取消链接,文件仍然存在于文件系统中,因为您没有关闭它(引用计数器仍然为1),您可以读取/写入它。但一旦程序退出,引用计数器将下降到0,并且标记为“已删除”,文件将自动删除。因此,当您希望确保程序一终止(通常或出现任何错误)文件就消失时,这是一种方法。