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;
}
答案 0 :(得分:2)
shm_open / shm_unlink不会直接影响内存映射,必须使用相应的mmap / munmap-calls来完成。
shm_unlink从shm-filesystem中删除Posix共享内存段,如果删除了最后一个映射,则实际内存将被销毁。
答案 1 :(得分:1)
如shm_unlink man页面中所述:
“在shm_unlink()返回之前应删除该名称,但是内存对象内容的删除应推迟到 对共享内存对象的所有打开和映射引用都是 除去“。
这意味着取消链接后内存可能仍然存在。
答案 2 :(得分:1)
shm_open
创建一个命名的共享内存对象。任何进程都可以使用传递给shm_open
的名称映射该共享内存对象。 shm_unlink
删除该名称,因此无法再映射共享内存区域,但实际内存在未映射之前是可用的。请注意,这类似于unlink
:您可以在open()
之后使用unlink()
ed文件,并且在最后一个文件描述符为close()
d之后将释放实际文件内容。
根据手册页:
shm_unlink()的操作类似于unlink(2):它删除了一个 共享内存对象名称,并且,一旦所有进程都取消映射 对象,取消分配和销毁关联的内容 记忆区域。成功shm_unlink()后,尝试 shm_open()具有相同名称的对象将失败(除非O_CREAT是 指定,在这种情况下创建一个新的,不同的对象。)