您好,登录后才能下订单哦!
C++共享内存删除的陷阱是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
当进程结束使用共享内存区时,要通过函数 shmdt
断开与共享内存区的连接。该函数声明在 sys/shm.h 中,其原型如下:
int shmdt(const void *shmaddr);
参数 shmaddr 是 shmat 函数的返回值。
进程脱离共享内存区后,数据结构 shmid_ds
中的 shm_nattch
就会减 1 。但是共享段内存依然存在,只有 shm_attch
为 0 后,即没有任何进程再使用该共享内存区,共享内存区才在内核中被删除。一般来说,当一个进程终止时,它所附加的共享内存区都会自动脱离。
我们通过:
int shmctl( int shmid , int cmd , struct shmid_ds *buf );
来删除已经存在的共享内存:
第一个参数,shmid
,是由shmget所返回的标记符。
第二个参数,cmd
,是要执行的动作。他可以有三个值:
命令 描述:
IPC_STAT
设置shmid_ds
结构中的数据反射与共享内存相关联的值。
IPC_SET
如果进程有相应的权限,将与共享内存相关联的值设置为shmid_ds
数据结构中所提供的值。
IPC_RMID
删除共享内存段。
第三个参数,buf,是一个指向包含共享内存模式与权限的结构的指针,删除的时候可以默认为0。
如果共享内存已经与所有访问它的进程断开了连接,则调用IPC_RMID子命令后,系统将立即删除共享内存的标识符,并删除该共享内存区,以及所有相关的数据结构;
如果仍有别的进程与该共享内存保持连接,则调用IPC_RMID子命令后,该共享内存并不会被立即从系统中删除,而是被设置为IPC_PRIVATE状态,并被标记为”已被删除”(使用ipcs命令可以看到dest字段);直到已有连接全部断开,该共享内存才会最终从系统中消失。
需要说明的是:一旦通过shmctl对共享内存进行了删除操作,则该共享内存将不能再接受任何新的连接,即使它依然存在于系统中!所以,可以确知, 在对共享内存删除之后不可能再有新的连接,则执行删除操作是安全的;否则,在删除操作之后如仍有新的连接发生,则这些连接都将可能失败!
Shmdt和shmctl的区别:
hmdt
是将共享内存从进程空间detach
出来,使进程中的shmid
无效化,不可以使用。但是保留空间。
而shmctl
(sid,IPC_RMID,0)则是删除共享内存,彻底不可用,释放空间。
关于C++共享内存删除的陷阱是怎样的问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。