C++共享内存删除的陷阱

作者:CPP开发前沿 时间:2022-04-03 12:30:37 

文章转自微信公众号:CPP开发前沿

当进程结束使用共享内存区时,要通过函数 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++,共享,内存,删除,陷阱
0
投稿

猜你喜欢

  • 基于C#后台调用跨域MVC服务及带Cookie验证的实现

    2023-06-08 11:32:26
  • 关于springboot2.4跨域配置问题

    2022-05-01 17:02:15
  • C#实现BBcode转为Markdown的方法

    2021-10-11 12:34:12
  • springboot创建线程池的两种方式小结

    2022-07-12 09:27:19
  • Java数据结构 递归之迷宫回溯案例讲解

    2023-04-01 11:16:38
  • maven实现jar包导入+导出方式

    2023-12-13 03:32:22
  • Spring AOP中的JDK和CGLib动态代理哪个效率更高?

    2023-07-02 18:42:50
  • Java读取txt文件中的数据赋给String变量方法

    2022-08-04 22:32:19
  • Android实现毛玻璃效果的对话框

    2021-07-19 03:28:42
  • SpringBoot2 参数管理实践之入参出参与校验的方式

    2022-12-25 02:44:30
  • 解析Java实现随机验证码功能的方法详解

    2022-09-25 23:26:14
  • 零基础学Java:Java开发工具 Eclipse 安装过程创建第一个Java项目及Eclipse的一些基础使用技巧

    2022-09-05 03:46:03
  • 很详细的android序列化过程Parcelable

    2021-09-15 20:03:51
  • SpringBoot整合Pulsar的实现示例

    2021-10-09 17:39:35
  • 详解Mybatis中的select方法

    2023-06-10 05:44:49
  • idea热部署插件jrebel正式版及破解版安装详细图文教程

    2023-05-27 03:28:59
  • JAVA基础之注解与反射的使用方法和场景

    2022-02-23 19:50:00
  • Android实现屏幕录制功能

    2022-10-29 15:26:36
  • Java Scanner输入两个数组的方法

    2022-06-07 08:21:20
  • 详细介绍idea如何设置类头注释和方法注释(图文)

    2022-05-08 20:22:41
  • asp之家 软件编程 m.aspxhome.com