C++ 创建共享内存

2023-11-06

共享内存用于实现进程间大量的数据传输,共享内存是在内存中单独开辟一段内存空间,这段内存空间有自己特有的数据结构,包括访问权限、大小和最近访问时间等。

1、shmget函数

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);

作用:得到或者创建共享内存

参数:

key:  创建共享内存的标识符,最好用16进制表示。

size:  创建共享内存段的字节数大小。 

flag: 共享内存段的创建标识

  • IPC_CREAT //如果不存在就创建
  • IPC_EXCL //如果存在则返回失败
  • IPC_NOWAIT //如不等待直接返回

返回值:(1)成功,返回共享内存标识符(2)出错,返回-1,错误原因存于errno中。

2、shmat函数

#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);

作用: 将当前进程与共享内存shmid建立链接,shmat返回指定共享内存的映射地址

参数:

shmid:共享内存空间标识符,即ID。

shmaddr:指定共享内存的映射地址。如果为0(NULL),则由系统选择映射的地址,推荐设置为0。如果非0,并且没有指定SHM_RND,则该值即为映射共享内存的地址。

shmflag: 指定共享内存的访问权限和映射条件,一般设置为0,即读写权限。

/* Flags for `shmat'.  */
#define SHM_RDONLY    010000        /* attach read-only else read-write */
#define SHM_RND        020000           /* round attach address to SHMLBA */
#define SHM_REMAP    040000          /* take-over region on attach */
#define SHM_EXEC    0100000           /* execution access */

3、shmdt函数

#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);

作用:shmdt是shmat的反操作,用于将共享内存和当前进程分离。在共享内存使用完毕后都要调用该函数。

参数:shmaddr:指定共享内存的映射地址。

返回值:成功:0,出错:-1,错误原因存在于errno中。

4、shmctl函数

#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

作用:共享内存的内存管理

参数:shmid:共享内存空间标识符,即ID。

cmd:

  • 公共的IPC选项(ipc.h中):
    • IPC_RMID //删除
    • IPC_SET //设置ipc_perm参数
    • IPC_STAT //获取ipc_perm参数
    • IPC_INFO //如ipcs
  • 共享内存自己的选项(shm.h中)【需要root权限】
    • SHM_LOCK //锁定共享内存段
    • SHM_UNLOCK //解锁共享内存段

 buf:共享内存管理结构体。具体说明参见共享内存内核结构定义部分,一般设置为0.

返回值:成功:0,出错:-1,错误原因存在于errno中。

共享内存的代码如下:

#include <iostream>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <thread>
#define SHARE_MEM_SIZE 2048
int main()
{
    int shmid = 0;  //内存标识符

    //创建共享内存
    shmid = shmget((key_t)0x5005,SHARE_MEM_SIZE,0640|IPC_CREAT);
    if(-1 == shmid)
    {
        std::cout << "create shareMem failed." << std::endl;
        return -1;
    }

    char* pMemSharedMem = 0;

    //将当前进程与共享内存shmid建立链接,shmat返回指定共享内存的映射地址
    pMemSharedMem = (char*)shmat(shmid,0,0);
    std::cout << "read context: " << pMemSharedMem << std::endl;


    std::string strContext = "hello world, "+ std::to_string(getpid());
    strncpy(pMemSharedMem,strContext.c_str(),strContext.length());
    std::cout << "write after: " << pMemSharedMem << std::endl;

    //shmat的反操作,将共享内存与当前进程分离
    shmdt(pMemSharedMem);


#if 0
    //操作共享内存, IPC_RMID //删除共享内存,在不使用共享内存的时候进行调用
    if(shmctl(shmid,IPC_RMID,0) == -1)
    {
        std::cout << "delete shared Mem fialed." << std::endl;
        return -1;
    }
#endif
    return 0;
}

第一次运行结果如下:

第二次运行结果如下:

上面的例子存在进程间的同步问题,可以结合信号量的用法来同步进程间的数据操作。

 5、查看创建共享内存命令:ipcs -m

       删除共享内存的命令:ipcrm -m shm_id

具体例子可参考共享内存查看删除等_٩(•̮̮̃•̃)۶的博客-CSDN博客

附加:

共享内存的创建函数也可参考:

共享内存 - shmdt - 《Linux API速查手册》 - 书栈网 · BookStack

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 创建共享内存 的相关文章

随机推荐

  • 数据包协议设计(通讯协议的设计)

    一 为什么要设计通讯协议 通常 多设备之间进行通讯多使用数据包的方式 如何从一堆的数据中确定哪些是有效数据 以及这些数据要表达什么意思 为解决这些问题 通常我们需要设计一个通讯协议 依照通讯协议对数据进行解析 就能够正确的找到并使用这些数据
  • 上下文相关音素-状态绑定

    在发音过程中 因为协同发音的影响 同一个音素在不同的位置 其发音变化很大 如下图所示 同样的元音 eh 在不同的单词中的发音在频域上区分非常明显 因为单音素monophone 是上下文独立的 context independent 为了能够
  • RabbitMQ中的限流、return机制、死信队列

    目录 优点 缺点 1 限流 2 return机制 3 死信队列 优点 高可用性 RabbitMQ支持集群和镜像队列等多种方式实现高可用性 保证系统稳定运行 可靠性强 RabbitMQ使用AMQP协议作为消息传递的标准 能够确保消息传递的可靠
  • TypeError: __init__() got an unexpected keyword argument 'categorical_features'

    我的代码 scikit learn 0 22 1 python 3 7 4 错误如下 TypeError init got an unexpected keyword argument categorical features 错误提示的意
  • Visio中插入Mathtype公式

    Visio中插入Mathtype公式 打开visio软件 依次点击 插入 对象 mathtype 6 0 equation 确定 也可以得到我们想要的公式 点击 对象 然后显示出Mathtype公式 点击 Mathtype 7 0 然后显示
  • step7-micro/win 在win10系统下安装步骤

    1 摘要 安装不成功可以多尝试几次 别人安装N次 下载过N个安装包 也就这个安装包安装成功了 其他的不成功 原因尚未可知 2 准备工作 软件包链接 https pan baidu com s 1VcKuwNO3czAi0zSbJiqjDw
  • 关于老赵让改成bootstrap框架搭建的过程

    客户就是上帝 你大爷的 jsp代码 数据与springMvc交互
  • 做一个Spring Boot小例子

    在我的 Spring Boot 框架介绍和使用 里介绍了Spring Boot 但是没有例子 所以这一篇的主要内容就是来做一个小例子 结合我上面那篇一起看效果更佳 运行项目 创建项目和上篇文章一样 我用了2 0的快照版本的Spring Bo
  • sum1(2,3)和sum1(2)(3)

    function sum1 x y var n x if y return x y else return function y return n y sum1 2 3 sum1 2 3 function sum var num argum
  • Python的nonlocal与global关键字

    nonlocal和global是Python中用于在函数内部访问外部作用域变量的关键字 一 nonlocal关键字 nonlocal用于在嵌套函数中修改外部函数的局部变量 当在一个函数内部定义了另一个函数 并且内部函数想要修改外部函数的局部
  • IAP与APP(一):两个固件使用Keil5默认设置编译后,利用J-Flash偏移APP的地址然后合并IAP烧写,运行时出现在跳转APP时无限重启的现象

    最近做了个在线升级 并没有使用系统 芯片 STM32F103C8T6 环境 Keil 5 STM32CubeMX 5 2 1 跳转和写FLASH在网上一搜其实不少 主要注意要重定向中断向量表和跳转前要关闭所有中断 在写好IAP和APP两个固
  • linux嵌入式开发常用下载链接

    linux kernel ARM 开源wike ARM GNU编译工具链下载
  • DS18B20温度传感器简介和1-Wire驱动程序

    目录 DS18B20简介 DS18B20的两种供电方式 64位ROM 温度传感器 1 Wire Bus简介 DS18B20通信时序 初始化 ROM相关命令 后续包含任何数据交换的操作 功能相关命令 后续包含任何数据交换的操作 单个DS18B
  • python数据库编程:Python连接Mssql基础教程之Python库pymssql

    前言 pymssql模块是用于sql server数据库 一种数据库通用接口标准 的连接 另外pyodbc不仅限于SQL server 还包括Oracle MySQL Access Excel等 另外除了pymssql pyodbc还有其他
  • SQL 表连接学习总结

    1 3种连接 完全外部连接 所有表都连接 允许null值存在 内连接 select字段名 from表名1 inner join表名2 on表名1 字段名 表名2 字段名 注意内连接inner可以省略 直接使用join默认为内连接 剔除含有空
  • mysql 非安装版的一个自动安装脚本及工具(更新版)

    原文地址 http blog csdn net iihero article details 5596401 脚本如下 将其放到解压以后的目录里边执行即可 plain view plain copy print echo off echo
  • Python2转Python3 中报错AttributeError: ‘generator‘ object has no attribute ‘next‘

    g next has been renamed to g next The reason for this is consistency special methods like init and del all have double u
  • STL容器之vector

    Vector总览 vector是C 标准模板库中的部分内容 它是一个多功能的 能够操作多种数据结构和算法的模板类和函数库 vector之所以被认为是一个容器 是因为它能够像容器一样存放各种类型的对象 简单地说 vector是一个能够存放任意
  • 从今天起,不再为 API 烦恼 !

    做技术管理的童鞋 往往会陷入这样一种困境 疲于奔命 到处救火填坑 沟通推进 却挤不出时间思考对团队和项目来说真正重要的事情 你有没有经历过这样的场景 1 下属老是改了接口但不维护文档 屡说不改 2 后端改了接口没有及时通知前端和测试 导致下
  • C++ 创建共享内存

    共享内存用于实现进程间大量的数据传输 共享内存是在内存中单独开辟一段内存空间 这段内存空间有自己特有的数据结构 包括访问权限 大小和最近访问时间等 1 shmget函数 include