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

文章转自微信公众号: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)

相关推荐

  • python和C++共享内存传输图像的示例

    原理 python没有办法直接和c++共享内存交互,需要间接调用c++打包好的库来实现 流程 C++共享内存打包成库 python调用C++库往共享内存存图像数据 C++测试代码从共享内存读取图像数据 实现 1.c++打包库 创建文件 example.cpp #include <iostream> #include <cassert> #include <stdlib.h> #include <sys/shm.h> #include "opencv

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

    文章转自微信公众号:CPP开发前沿 当进程结束使用共享内存区时,要通过函数 shmdt 断开与共享内存区的连接.该函数声明在 sys/shm.h 中,其原型如下: int shmdt(const void *shmaddr); 参数 shmaddr 是 shmat 函数的返回值. 进程脱离共享内存区后,数据结构 shmid_ds 中的 shm_nattch 就会减 1 .但是共享段内存依然存在,只有 shm_attch 为 0 后,即没有任何进程再使用该共享内存区,共享内存区才在内核中被删除.一

  • Linux共享内存实现机制的详解

    Linux共享内存实现机制的详解 内存共享: 两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进程A可以即时看到进程B对共享内存中数据的更新,反之亦然.由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以. 效率: 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据[1]: 一次从输入文件到

  • PHP共享内存用法实例分析

    本文实例讲述了PHP共享内存用法.分享给大家供大家参考,具体如下: 共享内存主要用于进程间通信 php中的共享内存有两套扩展可以实现 1.shmop  编译时需要开启 --enable-shmop 参数 实例: $shm_key = ftok(__FILE__, 't'); /** 开辟一块共享内存 int $key , string $flags , int $mode , int $size $flags: a:访问只读内存段 c:创建一个新内存段,或者如果该内存段已存在,尝试打开它进行读写

  • 详解Linux进程间通信——使用共享内存

    一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样.而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程. 特别提醒:共享内存并未提供同步机制,也就是说,在第一个进程结束

  • 单台服务器的PHP进程之间实现共享内存的方法

    开发人员要想使php进程实现共享内存的读写,首先就要支持IPC函数,即php编译安装时指定:--enable-shmop  与--enable-sysvsem 两个选项. IPC (Inter-process communication) 是一个Unix标准机制,它提供了使得在同一台主机不同进程之间可以互相的方法.基本的IPC处理机制有3种:它们分别是共享内存.信号量和消息队列.本文中我们主要讨论共享内存和信号量的使用. 在不同的处理进程之间使用共享内存是一个实现不同进程之间相互的好方法.如果你

  • PHP共享内存使用与信号控制实例分析

    本文实例讲述了PHP共享内存使用与信号控制.分享给大家供大家参考,具体如下: 共享内存 共享内存的使用主要是为了能够在同一台机器不同的进程中共享一些数据,比如在多个 php-fpm 进程中共享当前进程的使用情况.这种通信也称为进程间通信(Inter-Process Communication),简称 IPC. PHP 内置的 shmop 扩展 (Shared Memory Operations) 提供了一系列共享内存操作的函数(可能是用的人不多吧,这一块儿的文档还没有中文翻译).在 Linux

  • 解决Linux system v 共享内存问题

    system v 共享内存 #include <sys/types.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int shmflg); 建立:进程与共享内存的关联关系 key_t key:16进制的非0数字. 一般有两种方式设置它. 第一种:调用fotk函数 第二章:直接使用IPC_PRIVATE size:共享内存的大小 shmflg: IPC_CREAT IPC_EXCL 用户,组用户,其他用户对这片内

  • php进程(线程)通信基础之System V共享内存简单实例分析

    本文实例讲述了php进程(线程)通信基础之System V共享内存.分享给大家供大家参考,具体如下: PHP默认情况没有开启功能,要支持该功能在编译PHP的时候要加入下面几个选项  System V消息,--enable-sysvmsg   System V信号量支持,--enable-sysvsem  System V共享内存支持,--enable-sysvshm PHP还挺shmop共享内存,在编译的时候开启 --enable-shmop System V共享内存的相关函数: 1: 创建信号

  • nginx共享内存机制详解

    nginx的共享内存,是其能够实现高性能的主要原因之一,而其主要是用于对文件的缓存.本文首先会讲解共享内存的使用方式,然后会讲解nginx是如何实现共享内存的管理的. 1. 使用示例 nginx声明共享内存的指令为: proxy_cache_path /Users/Mike/nginx-cache levels=1:2 keys_zone=one:10m max_size=10g inactive=60m use_temp_path=off; 这里只是声明的一个名称为one,最大可用内存为10g

  • php使用shmop函数创建共享内存减少负载的方法

    PHP做内存共享有两套接口.一个是shm,它实际上是变量共享,会把对象变量序列化后再储存.使用起来倒是挺方便,但是序列化存储对于效率优先的内存访问操作而言就没啥意义了.另外一个是shmop,它是Linux和Windows通用的,不过功能上比shm弱了一些,在 Linux 上,这些函数直接是通过调用 shm* 系列的函数实现,而 Winodows 上也通过对系统函数的封装实现了同样的调用. 要创建共享内存段需要使用函数shmop,那么前提需要开启扩展. shmop主要函数 shmop_open (

随机推荐