6.12 共享内存(内存映射的使用、注意事项、进程间通信、systemV共享内存)

news2025/2/13 2:25:22

目录

system V IPC

共享内存

共享内存使用步骤

system V IPC -key

 system V IPC -ftok

 system V IPC -ftok-示例

共享内存创建-shmget

共享内存创建-shmget-示例1

共享内存创建-shmget-示例2

共享内存映射-shmat

共享内存读写 - 示例

共享内存撤销映射 - shmdt

共享内存撤销映射 - shmctl

共享内存 - 注意事项


system V IPC

IPC 对象包含: 共享内存、消息队列和信号灯集 每个IPC对象有唯一的ID 用Key关联 IPC对象创建后一直存在,直到被显式地删除 ipcs / ipcrm

共享内存

共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝 共享内存在内核空间创建,可被进程映射到用户空间访问,使用灵活 由于多个进程可同时访问共享内存,因此需要同步和互斥机制配合使用

共享内存使用步骤

生成key
创建/打开共享内存
映射共享内存,即把指定的共享内存映射到进程的地址空间用于访问
读写共享内存
撤销共享内存映射
删除共享内存对象

system V IPC -key

 system V IPC -ftok

 #include  <sys/types.h>
 #include <sys/ipc.h>
 key_t  ftok(const char *path,  int proj_id);
 //成功时返回合法的key值,失败时返回EOF
 path  //存在且可访问的文件的路径
 proj_id  //用于生成key的数字,范围1-255。

 system V IPC -ftok-示例

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>  
#include <sys/ipc.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
   key_t key;

   if ((key = ftok(“.”, ‘a’)) == -1) {
      perror(“key”);
      exit(-1);
   }   

共享内存创建-shmget

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

 //成功时返回共享内存的id,失败时返回EOF
 key  //和共享内存关联的key,IPC_PRIVATE 或 ftok生成
 shmflg //共享内存标志位  IPC_CREAT|0666

共享内存创建-shmget-示例1

//要求:创建一个私有的共享内存,大小为512字节,权限为0666
  int shmid;
  if ((shmid = shmget(IPC_PRIVATE, 512, 0666)) < 0) {
     perror(“shmget”);
     exit(-1);
  }

共享内存创建-shmget-示例2

//要求:创建/打开一个和key关联的共享内存,大小为1024字节,权限为0666
  key_t key;
  int shmid;

  if ((key = ftok(“.”, ‘m’)) == -1) {
     perror(“ftok”);
     exit(-1);
  }
  if ((shmid = shmget(key, 1024, IPC_CREAT|0666)) < 0) {
     perror(“shmget”);
     exit(-1);
  }

共享内存映射-shmat

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

  //成功时返回映射后的地址,失败时返回(void *)-1
  shmid   //要映射的共享内存id
  shmaddr //映射后的地址, NULL表示由系统自动映射
  shmflg  //标志位  0表示可读写;SHM_RDONLY表示只读

共享内存读写 - 示例

//通过指针访问共享内存,指针类型取决于共享内存中存放的数据类型

//例如:在共享内存中存放键盘输入的字符串 

      char *addr;
      int  shmid;
      
      if ((addr = (char *)shmat(shmid, NULL, 0)) == (char *)-1) {
         perror(“shmat”);
         exit(-1);
      }
      fgets(addr, N, stdin);
      

共享内存撤销映射 - shmdt

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

 //成功时返回0,失败时返回EOF
 //不使用共享内存时应撤销映射
 //进程结束时自动撤销

共享内存撤销映射 - shmctl

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

 //成功时返回0,失败时返回EOF
  shmid //要操作的共享内存的id
  cmd   //要执行的操作  IPC_STAT  IPC_SET  IPC_RMID
  buf   //保存或设置共享内存属性的地址

共享内存 - 注意事项

每块共享内存大小有限制
  ipcs  -l
  cat  /proc/sys/kernel/shmmax

共享内存删除的时间点
  添加删除标记
  nattach 变成0时真正删除


笔记:

内存映射

概念:

使一个磁盘文件与内存中的一个缓冲区相映射,进程可以像访问普通内存一样对文件进行访问,不必再调用read,write。

mmap()的优点

实现了用户空间和内核空间的高效交互方式

函数定义:

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

功能:创建共享内存映射

函数返回值:成功返回创建的映射区首地址,失败返回MAP_FAILED( ((void *) -1) ),设置errno值

参数说明:

addr:指定要映射的内存地址,一般设置为 NULL 让操作系统自动选择合适的内存地址。

length:必须>0。映射地址空间的字节数,它从被映射文件开头 offset 个字节开始算起。

prot:指定共享内存的访问权限。可取如下几个值的可选:PROT_READ(可读), PROT_WRITE(可写), PROT_EXEC(可执行), PROT_NONE(不可访问)。

flags:由以下几个常值指定:MAP_SHARED(共享的) MAP_PRIVATE(私有的), MAP_FIXED(表示必须使用 start 参数作为开始地址,如果失败不进行修正),其中,MAP_SHARED , MAP_PRIVATE必选其一,而 MAP_FIXED 则不推荐使用。MAP_ANONYMOUS(匿名映射,用于血缘关系进程间通信)

fd:表示要映射的文件句柄。如果匿名映射写-1。

offset:表示映射文件的偏移量,一般设置为 0 表示从文件头部开始映射。

注意事项:

(1) 创建映射区的过程中,隐含着一次对映射文件的读操作,将文件内容读取到映射区。

(2) 当MAP_SHARED时,要求:映射区的权限应 <=文件打开的权限(出于对映射区的保护),如果不满足报非法参数(Invalid argument)错误。

当MAP_PRIVATE时候,mmap中的权限是对内存的限制,只需要文件有读权限即可,操作只在内存有效,不会写到物理磁盘,且不能在进程间共享。

(3) 映射区的释放与文件关闭无关,只要映射建立成功,文件可以立即关闭。

(4) 用于映射的文件大小必须>0,当映射文件大小为0时,指定非0大小创建映射区,访问映射地址会报总线错误,指定0大小创建映射区,报非法参数错误(Invalid argument)

(5) 文件偏移量必须为0或者4K的整数倍(不是会报非法参数Invalid argument错误).

(6)映射大小可以大于文件大小,但只能访问文件page的内存地址,否则报总线错误 ,超出映射的内存大小报段错误

(7)mmap创建映射区出错概率非常高,一定要检查返回值,确保映射区建立成功再进行后续操作。

mmap()映射的种类:

1基于文件的映射

2 匿名映射

适用于具有亲缘关系的进程之间

释放内存映射

munmap函数

int munmap(void *addr, size_t length);

返回值:成功返回0,失败返回-1,并设置errno值。

函数参数:

addr:调用mmap函数成功返回的映射区首地址

length:映射区大小(即:mmap函数的第二个参数)

System V共享内存

IPC 的key

ftok函数

 key_t  ftok(const char *path,  int id);

  其中参数path是指定的文件名,这个文件必须是存在的而且可以访问的。id是子序号,它是一个8bit的整数。即范围是0~255。当函数执行成功,则会返回key_t键值,否则返回-1。在一般的UNIX中,通常是将文件的索引节点取出,然后在前面加上子序号就得到key_t的值

system V 共享内存使用步骤:

1创建/打开共享内存

2映射共享内存,即把指定的共享内存映射到进程的地址空间用于访问

3 读写共享内存

4 撤销共享内存映射

5 删除共享内存对象

查看共享内存命令ipcs

共享内存创建 – shmget

int shmget(key_t key, int size, int shmflg);

共享内存映射

void  *shmat(int shmid, const void *shmaddr, int shmflg);

第二个参数一般写NULL,表示自动映射

第三参数一般写0 ,表示可读写

共享内存撤销

 int  shmdt(void *shmaddr);

撤销后,内存地址不可再访问。

共享内存控制

int  shmctl(int shmid, int cmd, struct shmid_ds *buf);

shmctl(shmid, IPC_RMID, NULL);删除共享内存

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/645610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

etcd基本使用

目录 CRUD1、基本的put/get/del2、获取当前所有的key3、获取/删除带有前缀的键 lease使用1、创建lease&#xff0c;续租lease&#xff0c;撤销lease2、将lease attach到key上 watch使用watch、watch_oncereplacedeletewatch_prefix、watch_prefix_oncecancel_watchadd_watch_ca…

抖音整治短剧类小程序内容

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 短剧CPS项目这两年不是挺火的吗&#xff0c;很多草根创业者都在做短剧CPS当副业。 前两天&#xff0c;抖音开放平台团队发布公告&#xff1a; 近期&#xff0c;在微短剧类小程序内容合规排查中&am…

【LeetCode】HOT 100(11)

题单介绍&#xff1a; 精选 100 道力扣&#xff08;LeetCode&#xff09;上最热门的题目&#xff0c;适合初识算法与数据结构的新手和想要在短时间内高效提升的人&#xff0c;熟练掌握这 100 道题&#xff0c;你就已经具备了在代码世界通行的基本能力。 目录 题单介绍&#…

工作多年的工作焦虑症-广泛性焦虑症

我相信工作多年的人都会有自己的工作焦虑症的情况&#xff0c;而我们普通人最多的最容易的也就是广泛性焦虑症&#xff0c;广泛性焦虑障碍&#xff08;GAD&#xff09;是一种常见的慢性焦虑障碍&#xff0c;患者长时间处于一种担心、紧张、无法放松的状态。它会让一种广泛的担心…

采购协同:企业数字化转型的关键环节

企业数字化转型已成为当今市场的主流趋势&#xff0c;而采购协同作为企业数字化转型的关键环节&#xff0c;对于企业的成本控制、供应链管理等方面都有着至关重要的影响。本文将围绕采购协同的重要性、数字化转型的方法和优势、以及实现采购协同的关键环节展开讨论。 一、采购协…

Java并发容器 并发队列

并发容器概览 ConcurrentHashMap : 线程安全的HashMap CopyOnWriteArrayList: 线程安全的List BlockingQueue:这是一个接口&#xff0c;表示阻塞队列&#xff0c;非常适合用于作为数据共享的通道 ConcurrentLinkedQueue : 高效的非阻塞并发队列&#xff0c;使用链表实现。可…

目标检测数据集---道路破损缺陷数据集

✨✨✨✨✨✨目标检测数据集✨✨✨✨✨✨ 本专栏提供各种场景的数据集,主要聚焦:工业缺陷检测数据集、小目标数据集、遥感数据集、红外小目标数据集,该专栏的数据集会在多个专栏进行验证,在多个数据集进行验证mAP涨点明显,尤其是小目标、遮挡物精度提升明显的数据集会在该…

Java list安全删除元素详解

背景 前一段时间被问到了关于 List 集合的安全删除元素问题。一时间没反应过来这问题问的是什么&#xff0c;安全体现在什么地方&#xff0c;线程安全&#xff1f;线程安全可以保证元素粒度的数据唯一吗&#xff1f;删除是指什么&#xff0c;list.remove()&#xff1f; 带着这…

5外包功能测试做完,人废了一半····

先说一下自己的情况。大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近5年的点点点&#xff0c;今年年上旬&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01;而我已经在一个企业干了五年的功能测试…

剑指offer35 复杂链表的复制

复杂链表的复制 文章目录 复杂链表的复制方法一 回溯哈希表第二种解释 方法二&#xff1a;拼接拆分算法流程 参考文献 本题要求我们对一个复杂链表进行复制。在复杂链表中&#xff0c;每个节点除了有一个next指针指向下一个节点&#xff0c;还有一个random指针指向链表中的任意…

SpringBoot+Vue 车辆充电桩系统

文章目录 1、效果演示效果图技术栈 2、 前言介绍&#xff08;完整源码请私聊&#xff09;3、主要技术3.4.1 数据库概念结构设计3.4.2 数据库具体设计 4 系统功能的具体实现4.1 前台功能模块4.1.1 首页功能4.1.2 用户后台管理 4.2 后台功能模块4.2.1 管理员功能4.2.2 维修员功能…

后端(三):后端实战(表白墙的设计)

上一章结束了 Servlet 的学习&#xff0c;ok&#xff0c;现在我们已经学会了 1 1 了&#xff0c;现在开始我们要学会 百以内的加减乘除法。 本章就做一个最简单的 小小项目&#xff1a;表白墙。 在开始表白墙项目开始之间&#xff0c;我们先提前说好&#xff0c;这里主要跟关…

海思3559万能平台搭建:SPI输出h264码流

前言 面对各种各样的客户需求&#xff0c;spi接口也是一种传码流的形式&#xff0c;spi同步422可以保证抗干扰能力强的同时传输距离也很长&#xff0c;本文会介绍海思平台spi作为主机的发送功能以及发送码流的处理方式 1. 管脚复用&#xff1a; 首先需要配置的肯定是管脚复用&…

java容器排序

Java的容器 在Java中&#xff0c;我们想要保存对象可以使用很多种手段。最简单的就是数组。但是数组具有固定的尺寸&#xff0c;而通常来说&#xff0c;程序总是在运行时根据条件来创建对象&#xff0c;我们无法预知将要创建对象的个数以及类型&#xff0c;所以Java推出了容器…

动态规划-最长的回文序列

这里写自定义目录标题 1 描述2 样例2.1 样例12.2 样例2 3 解题思路以及实现方法3.1 解题思路3.1.1 确定状态3.1.2 转移方程3.1.3 初始条件和边界情况3.1.4 计算顺序 3.2 题解3.2.1 C实现3.2.2 java实现 该题是lintcode上 667 最长的回文序列&#xff0c;该题的解题思路亦是参…

方法选对,事半功倍:数据分析方法

人们发明了数据可视化&#xff0c;利用人类大脑更善于处理图像信息的特点&#xff0c;透过图形化的手段&#xff0c;用图表清晰有效地传达和沟通信息。把以往庞杂、繁乱的数据报表转化成简洁明了的可视化图表。 通过数据可视化制作出的图表&#xff0c;不再像传统分析方案那样…

JavaScript Web APIs学习总结

以后声明变量我们有限使用哪一个&#xff1f; const 有了变量先给const&#xff0c;如果发现它后面是要被修改的&#xff0c;再改为let 为什么const声明的对象可以修改里面的属性&#xff1f; 因为对象是引用类型&#xff0c;里面存储的是地址&#xff0c;只要地址不变&…

月入6000+的CSGO游戏搬砖项目操作细节和要求

月入6000的CSGO游戏搬砖项目操作细节和要求 最近咨询CSGO搬砖项目的人较多&#xff0c;在此整理一份统一的项目操作细节和要求。 1、什么是国外Steam游戏装备汇率差项目&#xff1f; 这个项目的基本原理是&#xff1a;购买国外Steam游戏平台上的装备&#xff0c;再在国内网易…

SSR渲染--02--nuxt demo(vue)

cmd 打开命令提示符&#xff0c;创建nuxt npm i create-nuxt-app -g create-nuxt-app vue-honor-of-kings&#xff08;这个是我的项目名&#xff0c;输入自己的项目名&#xff09; npm run dev创建的具体配置 【写demo为了方便&#xff0c;我直接下载了Element的包&#xff0…

游戏画面延迟的原因及解决方法

游戏画面延迟&#xff0c;是玩家在游戏中操作后&#xff0c;画面反应出现滞后或卡顿的现象。这会严重影响玩家的游戏体验和竞技水平&#xff0c;尤其是在一些需要高速反应和精确操作的3A大作中&#xff0c;画面延迟可能导致玩家错失良机或者被敌人击败。 那么&#xff0c;游戏…