首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在shm_unlink之后访问内存

在shm_unlink之后访问内存
EN

Stack Overflow用户
提问于 2016-01-18 00:47:04
回答 3查看 2.2K关注 0票数 7

对我来说,shm_unlink的操作并不清楚。我已经创建了一个共享内存对象并映射到一个进程。后来,我对内存对象执行了shm_unlink。在shm_unlink之后,我可以访问相同的内存进行读写。那件事怎么可能?由于内存对象已被shm_unlink销毁,因此在本例中我预计会出现分段错误。但是,它没有发生吗?原因何在?shm_unlink到底在这里做什么?

下面是代码片段。

代码语言:javascript
运行
复制
main(int argc, char * argv[])
{
    int   fd;
    char  *addr;
    int i = 0;

    /*
    * In case the unlink code isn't executed at the end
    */
    if (argc != 1) {
        shm_unlink("/bolts");
        return EXIT_SUCCESS;
    }

    /* Create a new memory object */
    fd = shm_open("/bolts", O_RDWR | O_CREAT, 0666);
    if (fd == -1) {
        fprintf(stderr, "Open failed : %s\n",
            strerror(errno));
        return EXIT_FAILURE;
    }

    /* Set the memory object's size */
    if (ftruncate(fd, 1024) == -1) {
        fprintf(stderr, "ftruncate : %s\n", strerror(errno));
        return EXIT_FAILURE;
    }

    addr = mmap(0, 1024, PROT_READ | PROT_WRITE,
        MAP_SHARED, fd, 0);

    if (addr == MAP_FAILED) {
        fprintf(stderr, "mmap failed:%s\n", strerror(errno));
        return EXIT_FAILURE;
    }

    sleep(10);

    printf("Map addr is %x\n",(unsigned int) addr);

    if (fork())
    {
        sleep(10);
        strcpy (addr, "Sreehari in parent\n");
    }
    else
    {
        strcpy(addr,  "I am in child\n");

    }

    sleep(6);
    i = shm_unlink("/bolts");

    printf("addr is %s, i is %d \n", addr, i);
    return EXIT_SUCCESS;
}
EN

回答 3

Stack Overflow用户

发布于 2016-01-18 00:53:44

shm_open/shm_unlink不会直接影响内存映射,这必须通过相应的mmap/munmap-call来完成。

shm_unlink从shm-filesystem中删除了一个Posix共享内存段,如果删除了最后一个映射,那么实际的内存就会被销毁。

票数 4
EN

Stack Overflow用户

发布于 2016-01-18 16:35:05

shm_open创建一个命名的共享内存对象。任何进程都可以使用传递给shm_open的名称来映射该共享内存对象。shm_unlink删除了该名称,因此共享内存区域不能再映射,但实际内存在未映射之前是可用的。请注意,这类似于unlink:您可以在对文件执行unlink()后使用open()ed文件,并且在最后一个文件描述符为close()d之后,实际的文件内容将被释放。

根据手册页:

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

票数 4
EN

Stack Overflow用户

发布于 2016-01-18 00:53:25

如shm_unlink man页面中所述:

“该名称应在shm_unlink()返回之前删除,但内存对象内容的删除应推迟到对共享内存对象的所有打开和映射引用都已删除。”

这意味着在解除链接之后,内存可能仍然存在。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34840831

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档