对我来说,shm_unlink的操作并不清楚。我已经创建了一个共享内存对象并映射到一个进程。后来,我对内存对象执行了shm_unlink。在shm_unlink之后,我可以访问相同的内存进行读写。那件事怎么可能?由于内存对象已被shm_unlink销毁,因此在本例中我预计会出现分段错误。但是,它没有发生吗?原因何在?shm_unlink到底在这里做什么?
下面是代码片段。
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;
}发布于 2016-01-18 00:53:44
shm_open/shm_unlink不会直接影响内存映射,这必须通过相应的mmap/munmap-call来完成。
shm_unlink从shm-filesystem中删除了一个Posix共享内存段,如果删除了最后一个映射,那么实际的内存就会被销毁。
发布于 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,在这种情况下会创建一个新的、不同的对象)。
发布于 2016-01-18 00:53:25
如shm_unlink man页面中所述:
“该名称应在shm_unlink()返回之前删除,但内存对象内容的删除应推迟到对共享内存对象的所有打开和映射引用都已删除。”
这意味着在解除链接之后,内存可能仍然存在。
https://stackoverflow.com/questions/34840831
复制相似问题