【Linux】共享内存

2023-09-21 08:38:41

共享内存

当多个进程需要在其间共享数据时,共享内存提供了一种高效的方式。它允许多个进程将同一块内存映射到它们的地址空间中,使得它们可以直接读写该内存,而不需要通过消息传递或其他形式的通信。

系统接口

在Linux中,使用共享内存需要以下步骤:

  1. 创建共享内存区域:使用shmget系统调用来创建一个共享内存区域,并指定大小和权限。
  2. 连接到共享内存区域:使用shmat系统调用将共享内存区域连接到进程的地址空间中,返回指向共享内存的指针。
  3. 使用共享内存:通过使用指针可以直接读写共享内存。
  4. 分离共享内存:使用shmdt系统调用将共享内存从进程的地址空间中分离。
  5. 删除共享内存区域:使用shmctl系统调用可以删除共享内存区域。
    共享内存是一种强大的进程间通信机制,但它也需要谨慎使用,因为多个进程可以直接修改共享内存中的数据,所以需要通过其他方式(如信号量)来确保数据的正确性和一致性。在编程中,可以使用C语言中的<sys/shm.h>头文件提供的函数来进行共享内存的操作。

在这里插入图片描述

当释放共享内存的时候,要先切断他们的映射关系,再释放共享区

创建共享内存区域 shmget
//shmget所在的头文件和声明
#include <sys/ipc.h>
#include <sys/shm.h>

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

当创建成功后,返回共享内存的编号shmid,进程之间调用同一个共享内存的shmid是相等的
当创建失败后返回-1
在这里插入图片描述

key
在这里插入图片描述

  • 共享内存是操作系统在内存中申请的一块内存空间,操作系统中可能会有大量的共享内存,操作系统为了管理这些共享内存就要用相应的结构来进行描述,每个共享内存都有自己唯一的标识来代表。
  • 函数作用: 系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值。通常情况下,该id值通过ftok函数得到
	#include <sys/types.h>
    #include <sys/ipc.h>

    key_t ftok(const char *pathname, int proj_id);

pathname用于产生key_t值的文件名(文件必须存在)
proj_id的低序8位(不能为0)
在这里插入图片描述
在这里插入图片描述

size

  • size参数用于指明要创建的共享内存的大小,单位为字节。
  • 操作系统创建共享内存是以page页为单位的,大小为4KB。

shmflg
shmflg参数用于指明shmget的使用模式。
IPC_CREAT and IPC_EXCL
单独使用IPC_CREAL:创建一个共享内存,如果共享内存不存在,就创建之,如果已经存在,获取已经存在的共性内存并返回
IPC_EXCL不能单独使用,一般都要配合IPC_CREAT
IPC_CREAT | IPC_EXCL:创建一个共享内存,如果共享内存不存在,就创建之,如果已经存在,则立马报错返回
– 如果创建成功,对应的shm,一定是最新的

关联共享区域 shmat

当使用共享内存时,需要将其先与要映射的进程进行关联,才可以进行通信

//shmat所在的头文件和声明
#include <sys/types.h>
#include <sys/shm.h>

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

shmid:shmget创建共享内存时的返回值
shmaddr:指明要关联到的地址处,传入空指针操作系统会自己进行关联。
shmflg:指明对要关联的共享内存的权限,传入0为读写权限。
如果关联成功则返回其对应的虚拟地址,失败返回-1

去除共享关联 shmdt

当要进行删除共享内存的时候,我们需要将其的关联全部去除后,才可以正常删除共享内存

//shmdt所在的头文件和声明
#include <sys/types.h>
#include <sys/shm.h>

int shmdt(const void *shmaddr);

shmaddr:为共享关联时,返回的虚拟地址
成功返回0,失败返回-1

删除共享内存区域

当共享内存的进程退出的时候,我们的共享内存还是存在的,它是随的os的退出而退出,而不是进程退出它就退出的
删除共享区域的方式有两种一种为命令删除ipcrm -m

另一种为调用系统函数删除shmctl

ipcrm选项介绍

ipcs表示多个通信资源,选项包括队列(-q),共享内存(-m),信号量(-a)
在这里插入图片描述
我们需要查看我们的共享内存时,可以通过-m选项来查看
在这里插入图片描述

ipcrm -m 加 shmid可以删除一个共享内存,这里是不可以通过key删除的
key类比文件的inode
shmid类比文件的fd
在这里插入图片描述

shmctl选项介绍

  #include <sys/ipc.h>
  #include <sys/shm.h>    

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

shmid:创建和读取共享进程时的返回值
cmd:对共享内存做操作(cmd选项有多种,其中包括,IPC_STAT 获取当前共享内存属性,IPC_SET 设置共享内存属性,IPC_RMID 标记这个段为释放)
*buf:获取共享内存字段属性,也是包括多种属性(删除时属性为nullptr)
如果函数发生错误返回-1

	int n = shmctl(shmid, IPC_RMID, nullptr);
    assert(n != -1);
    (void)n;

共享内存特性

  • 无需多余拷贝:使用共享内存通信不需要任何接口,只要共享内存被映射到进程地址空间中,进程就能看到共享内存。
  • 速度快:共享内存被映射到进程的地址空间中,进程就能看到共享内存,不涉及缓冲区,无需多余拷贝动作,因此共享内存通信速度很快。
  • 无保护:使用共享内存通信不需要任何接口,因此共享内存不存在任何保护机制。
更多推荐

【Java系列】深入解析 Lambda表达式

序言你只管努力,其他交给时间,时间会证明一切。文章标记颜色说明:黄色:重要标题红色:用来标记结论绿色:用来标记一级论点蓝色:用来标记二级论点希望这篇文章能让你不仅有一定的收获,而且可以愉快的学习,如果有什么建议,都可以留言和我交流1基础介绍1.1概念介绍JavaLambda表达式是Java8中最重要的新特性之一。它们是

MySQL常见面试题(三)

😀前言在当今数据驱动的时代,数据库管理成为企业和组织的核心组件。其中,数据库的性能优化是确保信息可以快速、准确地检索的关键要素。这通常通过正确实现和管理数据库索引来实现。索引不仅可以大大提高数据库的查询性能,还可以帮助维持数据的完整性和一致性。本文将深入探讨MySQL数据库中的不同类型的索引,包括其特点和实现方式。我

《计算机视觉中的多视图几何》笔记(6)

前面的1-5章在序号上被标为Part0,标题是TheBackground:ProjectiveGeometry,TransformationsandEstimation,讲述了一些背景知识,包括投影几何、变换和估计。接下来的部分进入到Part1,标题是CameraGeometryandSingleViewGeometr

CDN内容分发系统

CDN分发系统的架构。CDN系统的缓存,也是一层一层的,能不访问后端真正的源,就不打扰它。在没有CDN的情况下,用户向浏览器输入www.web.com这个域名,客户端访问本地DNS服务器的时候,如果本地DNS服务器有缓存,则返回网站的地址;如果没有,递归查询到网站的权威DNS服务器,这个权威DNS服务器是负责web.c

JavaScript Iterator 迭代器:简化集合遍历的利器

🎬岸边的风:个人主页🔥个人专栏:《VUE》《javaScript》⛺️生活的理想,就是为了理想的生活!目录引言1.迭代器的概念2.迭代器的属性3.迭代器的应用场景3.1数组遍历3.2对象遍历3.3Map遍历#3.4Set遍历4.自定义迭代器结论引言在JavaScript中,迭代器(Iterator)是一种用于遍历集

数据结构——图(图的基本概念)

文章目录前言一、图的基本概念图的定义总结前言图的基本概念1.1有向图1.2无向图1.3有向完全图1.4无向完全图1.5连通图一、图的基本概念图的定义图的定义:图G是顶点集V和边集E组成,记为G=(V,E),其中V(G)表示图G中顶点有限非空集,E(G)表示图G中顶点之间关系(边)的集合,图中顶点个数也叫图的阶,图不可以

解决 MyBatis-Plus + PostgreSQL 中的 org.postgresql.util.PSQLException 异常

🌷🍁博主猫头虎带您GotoNewWorld.✨🍁🦄博客首页——猫头虎的博客🎐🐳《面试题大全专栏》文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大

PostgreSQL 10.23 安装图文教程

目录一、PostgreSQL介绍二、下载安装包三、安装教程今天给大家分享Win10操作系统安装PostgreSQL10.23图文教程,希望对大家学习PostgreSQL能有所帮助!一、PostgreSQL介绍PostgreSQL(简称Postgres)是一款功能强大的开源关系型数据库管理系统,由PostgreSQLGl

深入理解 PostgreSQL 中的 MVCC(多版本并发控制)机制

🌷🍁博主猫头虎带您GotoNewWorld.✨🍁🦄博客首页——猫头虎的博客🎐🐳《面试题大全专栏》文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大

css知识学习系列(5)-每天10个知识点

目录1.**Flexbox和Grid布局都是为了解决布局问题,但它们有什么不同?**2.**CSS中的“overflow”属性与布局有什么关系?有哪些常见的使用场景?**3.**在CSS中,如何使用“position”属性和“z-index”属性实现元素的层级关系?**4.**CSS中的“@keyframes”有什么作

shell --- 基础篇

一、符号介绍$#脚本的参数个数$*以一个单字符串显示所有脚本传递的参数$$当前进程ID号$!后台运行的最后一个进程的ID号$@与$*相同,但是使用时加引号,并在引号中返回每个参数。$-显示Shell使用的当前选项,与set命令功能相同。$?显示最后命令的退出状态(或函数的返回值)。0表示没有错误三、基础语法echo--

热文推荐