SystemV 共享内存(一)—— 共享内存的创建与释放(shmget / shmctl)

2023-05-16

匿名管道和命名管道都是基于文件的进程间通信,SystemV方案是在OS内核层面专门为进程间通信设计的一个方案,然后通过系统调用(system call)给用户提供通信接口

SystemV方案包含三种:共享内存、消息队列、信号量

下面要说的就是共享内存的创建和释放


目录

一、什么是共享内存??

1、共享内存的定义

2、共享内存的特点

二、使用共享内存的准备和收尾工作

三、shmget函数(shared memory get)

1、 参数解析

(1) 第一个参数 key

(2) 第二个参数 size

(3) 第三个参数 shmget

2、返回值解析

3、使用shmget函数

4、共享内存的生命周期

四、shmctl(shared memory control)

1、参数解析

2、返回值解析

3、使用shmctl 函数

五、为什么共享内存的ID是0,1,2 ... ? 


一、什么是共享内存??

1、共享内存的定义

由于进程通信的本质是要让两个不同的进程看到同一份资源,我们可以在物理内存上开辟一块空间,这块空间被称为共享内存,然后让这两个进程通过某种方式都能访问到这块内存,这样的话,两个进程之间就可以通信了

2、共享内存的特点

第一,和创建进程类似,进程被创建的时候,会被分配一个pid来标识这个进程的唯一性,同时也方便OS管理这些进程,因此共享内存在被创建的时候,会被分配一个“ID”来标识唯一性

第二,共享内存可以允许存在多个,为了区分这些共享内存,我们上面引入了“ID”的概念,但是要如何让两个进程连上同一个共享内存呢??

就好比,我要和人solo(通信),我创建了一个房间(共享内存),这个房间就有了房间号(共享内存的ID),是个人都能进这个房间,根本没法通信,所以我们要设置房间密码。因此为了通信,我们需要两样东西,一个是房间号,一个是房间密码

二、使用共享内存的准备和收尾工作

当我们需要使用共享内存时,我们要做的准备工作是:

                — 通过某种调用,在内存中开辟一块空间(shmget)

                — 通过某种调用,让两个进程挂接到这个新开辟的空间上(shmat)

当我们不需要使用共享内存时,我们需要做的收尾工作是:

                — 断开进程和共享内存之间的关联(shmdt)

                — 释放共享内存(shmctl)

每一步都对应着一个系统调用接口,下面要说的就是这四个系统调用接口

三、shmget函数(shared memory get)

这是共享内存的创建函数,调用以后会向内核申请内存,但是需要注意的是,共享内存是以“页”为单位的,一页是4KB = 4096bytes,所以一般建议申请共享内存的大小是4KB的整数倍!

如果申请了4097个字节,那么OS会给你4096*2个字节的空间

1、 参数解析

下面是shmget函数的声明以及要用到的头文件

(1) 第一个参数 key

第一个参数是唯一标识编号,也就是前面说到的房间密码,这个是由用户自己设置的,一般是通过ftok函数来,也可以自己随意设置一个整数

 ftok函数的第一个参数:路径名

 ftok函数的第二个参数:项目ID

关于这个函数无需想的太复杂,简单来说就是,从路径名中取出一部分,然后再从ID中取出一部分,最后再把两部分组合一下形成一个整数,我们就把这个整数当作“房间密码”

注意:ftok被不同进程调用,只要路径名和ID是一样的,生成的整数就是一样的

(2) 第二个参数 size

 第二个参数是开辟共享内存的大小,一般建议是4KB的整数倍(原因详见第三部分开头)

(3) 第三个参数 shmget

第三个参数是创建共享内存的方式以及设置权限

 类似于write函数的第二个参数,属于位运算输入

IPC_CREAT:可以单独使用,如果共享内存不存在,则重新开辟,函数返回值是新开辟的共享内

                        存的ID;如果已经存在,则沿用已有的共享内存,函数返回值是已有的共享内存的

                        ID

IPC_EXCL:无法单独使用,要配合IPC_CREAT使用,即 IPC_CREAT | IPC_EXCL

IPC_CREAT | IPC_EXCL:如果共享内存不存在,则重新开辟,函数返回值是新开辟的共享内

                                        存的ID;如果已经存在,则报错

IPC_CREAT | IPC_EXCL | 0664:开辟共享内存的同时,设置共享内存的访问权限

2、返回值解析

如果共享内存开辟成功,则返回共享内存的ID(即房间号);否则返回 -1.

3、使用shmget函数

下面我们在使用shmget函数的同时要验证一下上面红色的注意事项

和之前的命名管道通信一样,继续使用server.c 和 client.c 来通信,公共数据放在common.h

 现在我们可以来看一下测试的结果,我们会发现服务端和客户端使用的密码是一样的,这也就验证了上面红色部分

 我们在命令行输入下面的指令查看创建好的共享内存

ipcs                     #显示SystemV方案的全部,即共享内存、消息队列、信号量
ipcs -m                  # -m 显示共享内存
ipcs -q                  # -q 显示共享消息队列
ipcs -s                  # -s 显示共享信号量

4、共享内存的生命周期

从上面的测试结果,我们会发现,进程退出以后,共享内存依然存在,换到我们之前的匿名管道,管道的生命周期是随进程的,进程退出以后,管道也就不存在了

共享内存不属于任何进程,不归进程管理,除非调用释放函数,否则要不要释放是OS决定的,因此共享内存的生命周期是随内核的!!

释放的方式有三种:

- 关机

- 调用释放共享内存的函数 shmctl

- 命令行释放

ipcrm -m 1             # ipcrm -m 共享内存的id

四、shmctl(shared memory control)

这是控制共享内存的函数,目前我们只需要知道,怎么通过这个函数释放共享内存即可

1、参数解析

下面是共享内存控制函数的函数声明及需要的头文件

第一个参数是 共享内存的id

第二个参数是 控制指令(我们选择删除共享内存的那个指令)

第三个参数是 shmid所指向的共享内存的地址,既然空间被释放以后,地址就赋值为null

2、返回值解析

释放成功则返回 0;释放失败返回 -1

3、使用shmctl 函数

我们在原本的server.c中加入下面的内容

 我们发现,共享内存最终被释放了

五、为什么共享内存的ID是0,1,2 ... ? 

我们观察上面的图,会发现shmid是 0,1,2这样的整数,和前面的文件一样,很容易联想到数组的下标。这确实是数组的下标,但是这个数组中存放着什么呢??

最开始也说了,共享内存以结构体的形式被管理着,消息队列和信号量也是如此,下面依次是共享内存、消息队列、信号量的结构体。

首先需要明确的是,上面这些共享内存的结构体shmid_ds、消息队列的结构体msgid_ds、信号量的结构体semid_ds都不是关键,关键的是这个ipc_perm

其次,每种资源都嵌套了ipc_perm结构体,我们只要知道了 各自ipc_perm的地址,就能通过C++切片寻找到每种资源的地址

因此,对每种资源结构体的管理就变成了对ipc_perm的管理 ——》 这里的shmid就是这个存储ipc_perm结构体地址的数组下标

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

SystemV 共享内存(一)—— 共享内存的创建与释放(shmget / shmctl) 的相关文章

  • 背包问题----分组背包(超详细讲解)

    树形dp 分组背包 43 依赖背包 分组背包1 定义2 讲解3 练习题 依赖背包1 定义2 讲解3 练习题 分组背包 1 定义 分组背包 xff0c 通俗的讲就是 xff0c 给你N组物品 xff0c 然后每一组你至多选择一个物品 也可以不
  • 树状数组(详细分析+应用),看不懂打死我!

    树状数组介绍 在学习一个算法之前一定要清楚它能干嘛 xff0c 能解决什么样的问题 xff0c 对你解题是否有帮助 xff0c 然后才去学习它 那么接下来看如下几个问题 什么是树状数组 顾名思义就是一个结构为树形结构的数组 xff0c 于二
  • 更新Win10版本后,wifi图标不见了,并且连接不到wifi和宽带,以及点击网络和Internet闪退的情况

    问题描述 你们是不是遇到过这样的问题 xff0c 更新系统前还好好的 xff0c 更新之后wifi图标不见了 于是你尝试点击最右边的图标打开wifi xff0c 如下图所示 但是你发现没有任何可连接wifi xff0c 就下面这样 xff0
  • Netty框架之Selector使用详解

    谈到Selector的具体使用 xff0c 那么就要结合BIO NIO的知识讲解 xff0c Selector使用在非阻塞模式NIO场景下 xff0c 学习NIO之前先要了解BIO原理 xff0c 下面我们一步步讲解 一 BIO Block
  • SpringBoot系列---application.yml配置文件

    1 yml配置文件格式 span class token comment 对象 span span class token key atrule person span span class token punctuation span s
  • Spring系列---SpringBoot配置-profiles

    1 profiles的作用 2 使用profiles span class token punctuation span span class token comment 开发环境 span span class token key atr
  • SpringBoot系列---SpringBoot配置文件加载顺序

    1 内部文件配置加载顺序 resource目录下打包之后就是classpath路径 xff0c 所以classpath路径下也就是resource目录下的配置文件 2 外部配置文件加载顺序我们再使用springboot开发程序的时候 xff
  • 4.7树的使用(并查集、哈夫曼树的构建)

    一 并查集 优化后 时间复杂度 xff1a 树高 O log2n 查找 xff1a O log2n 1 并查集初始化 span class token macro property span class token directive ha
  • 游标v_cur的%notfound

    当游标的值为空的时候 xff0c 处理无效员工的id时就会出现错误 比如 xff1a 创建一个程序检索某个员工的工龄 a 创建一个函数GET SERVICE YRS xff0c 检索某个员工总的工龄 xff1b 此函数应该接受员工ID作为输
  • 两个大数(包括负数)相加

    分析 xff1a 当这两个大数为正数时 xff0c 我们可以将字符转化为数字相加 xff0c 再加进位talg xff0c 有进位为1 xff0c 否则为0 xff1b 两个为负数则与正数相似 xff0c 为一正一负时 xff0c 我们可以
  • WRF模式运行的流程以及简单错误的避免

    前提安装好 WPS 43 WRF 43 WRFDomainWizard等组件 一 xff0c WPS 1 xff0c geogrid exe 准备静态数据 地理数据 2 xff0c ungrib exe 解压强迫场资料 气象数据 3 xff
  • 两台计算机之间的直连

    1 xff0c 直连线的要求 xff0c 需要交叉线 2 xff0c 在网络里打开适配器选项 xff0c 右击以太网 xff0c 打开属性 xff0c 双击IP4 xff0c 如图所示 IP地址设置如上图 3 xff0c 另一台计算机的设置
  • MP3转码PCM

    支持aac和mp3转码 xff0c 主要是dst nb sample的计算 xff0c aac大致为1024 xff0c MP3为1152 xff0c static int dst nb samples 61 0 define SWR in
  • RISC-V MCU 导盲手套

    RISC V MCU 导盲手套 关于本文队伍名称第一部分 设计概述1 1 设计目的1 2 应用领域1 3 主要技术特点1 4 关键性能指标1 5 主要创新点 第二部分 系统组成及功能说明2 1 整体介绍2 2 各模块介绍 第三部分 完成情况
  • 告别VMWARE!开源,免费,高效率,跨平台的

    与所有Linux爱好者一样 xff0c 对Windows的感情都是虽然不喜欢 xff0c 但是有些时候还真离不开这个玩意 那怎么办呢 xff1f 虚拟机 xff01 最早接触的虚拟机是virtualpc xff0c 这个软件自从被微软收购之
  • 保护机制

    一 SSP Stack Smashing Protection SSP属于编译器层面的防护 具体实现 1 xff0c 在栈中 xff0c ebp与变量之间插入随机值canary xff0c 用于监视是否栈溢出 xff1b 2 xff0c 在
  • Linux系统溢出漏洞学习

    系统环境 xff1a Linux 3 0 0 12 generic athlon DISTRIB DESCRIPTION 61 34 Ubuntu 11 10 34 gcc Ubuntu Linaro 4 6 3 1ubuntu5 4 6
  • db dw dd 与equ的区别

    此前在写汇编的过程中 xff0c 一直不理解两者间的区别 xff0c 例如 xff1a address1 dw 1000h address2 equ 2000h mov ax address1 mov bx address2 db dw d
  • c++/cmake/cmakelists/cmakelists子目录的添加

    cmake minimum required VERSION 3 10 project learning to create project set CMAKE CXX STANDARD 11 set LIBRARY OUTPUT PATH
  • RoboMaster怎么设计新步兵悬挂

    流程 xff1a 明确需求 gt 提出可量化目标 gt 方案提出与评估 gt 细化方案 gt 任务分配 gt 画图设计 gt 图纸提交与验收 gt 加工 gt 装配 gt 机械调试 需求 xff1a 性能优越的悬挂 目标 xff1a 1 任

随机推荐

  • windows7资源管理器无响应的解决方案

    windows7使用过程中常常会出现资源管理器无响应 xff0c 分多种情况 xff1a 1 xff0c 由于第三方程序大量占用内存 xff0c 系统响应速度变慢 xff0c 选择等待程序响应 xff0c 过一段时间即可恢复正常 xff1b
  • 黑客技巧:Google hacking实现以及应用

    前言 google hacking其实并算不上什么新东西 在早几年我在一些国外站点上就看见过相关的介绍 但是由于当时并没有重视这种技术 认为最多就只是用来找找未改名的mdb或者别人留下的webshell什么的 并无太大实际用途 但是前段时间
  • C语言string库函数介绍(附模拟实现)

    目录 strlen 模拟实现 strcpy 模拟实现 strcat 模拟实现 strcmp 模拟实现 strncpy strncat strncmp strstr 模拟实现 strlen size t strlen const char s
  • Realsense D435i Yolov5目标检测实时获得目标三维位置信息

    文章目录 一 效果演示二 环境配置三 模型配置四 相机配置五 部分代码 六 仓库链接 一 效果演示 Colorimage Colorimage and depthimage 二 环境配置 1 一个可以运行YOLOv5的python环境 pi
  • C语言中return的各种用法

    转自 xff1a https www pinlue com article 2021 06 2614 1611638969328 html
  • 从零开始搭二维激光SLAM --- 激光雷达数据效果对比

    我们知道 xff0c 不同品牌的激光雷达产生的数据是不一样的 xff0c 那这些不同点是如何影响建图效果的呢 xff1f 这篇文章就是来分析这个问题 xff0c 将从不同光强下的点云效果 xff0c 不同夹角下的点云效果 xff0c 以及
  • 海上垂直无人机垂直起降平台

    无人机的降落要实现对飞行轨迹和飞行状态的精确控制 xff0c 对目标地点的精确定位与识别 xff0c 而海上无人机降落具有更多不确定因素 xff0c 现提出一些有效方案 xff0c 以使得无人机海上起降成为可能 无人机起降条件 xff1a
  • 开源自制6通道航模遥控器,Arduino Pro Mini NRF24L01模块

    前言 前段时间跟着LOLI大神的教程制作了LOLI三代控 xff0c 效果很好 但是 xff0c 由于LOLI三代控的接收机带有数据回传功能 xff0c 也就是接收机的无线模块也承担了发射数据功能 xff0c 所以接收机也要使用带有功率放大
  • linux下TCP/IP通讯实例

    下面是server端源码 xff1a include lt stdio h gt include lt stdlib h gt include lt string h gt include lt unistd h gt include lt
  • STM32 USART 一些问题

    SECTION 1 1 2 3 4 5 6 7 8 9 10 11 12 13
  • 数据缓冲策略 —— 无缓冲、行缓冲、全缓冲(缓冲区大小测试)

    printf打印数据时 xff0c 一般会先把数据放入C缓冲区 xff0c 然后再刷新到内核缓冲区 xff0c 最后再写入硬件 这个过程中 xff0c 数据从C缓冲区迁移到内核缓冲区的操作我们称为缓冲 xff08 也可以理解为刷新 xff0
  • K210 FreeRTOS多任务多核系统调度

    一 目的 众所周知 xff0c K210这款AI新品是一款64bit 双核芯片 xff0c 其支持裸机编程 xff0c 并且官方也提供freertos sdk xff0c 方便开发者在其上进行多任务应用开发 那么如何进行任务创建和多核开发呢
  • keil如何添加h文件_KEIL 那些编辑技巧与方法

    当然了 xff0c 很多人现在更多的是使用 VSCode 或者 SI 等软件进行编辑 xff0c 但不可否认的是 xff0c 还有很多道友还是选择 KEIL 作为编辑软件的 xff0c 本篇笔记作为一个编辑技巧的总结 关于 KEIL 软件的
  • 关于keil C51 案例 加入头文件

    1 先在工程下面建立一个 h文件 xff0c 例如delay h 在其中写入要加入的函数声明 xff0c 或者其他的一些预定义 xff1a ifndef DELAY H define DELAY H include lt reg52 h g
  • "extern C", 你真的懂了吗?

    在c 43 43 prime书中看到过 xff0c 在DLL和lib中看到过 xff0c 但是每次看过就不求甚解地一扫而过 心里知道有extern c这个语句 xff0c 却不知道该用在哪里 xff0c 又能起到什么作用 唉 xff0c 想
  • 内存或寄存器定义和赋值

    在嵌入式中 xff0c 会经常遇到寄存器 内存的数据传输 xff0c 如何向寄存器中写入数据呢 xff1f 现举例说明 xff1a define rDISRC0 volatile unsigned 0x4b000000 DMA 0 Init
  • Makefile的文件格式,详解规则

    构建规则都写在Makefile文件里面 xff0c 要学会如何Make命令 xff0c 就必须学会如何编写Makefile文件 1 概述 Makefile文件由一系列规则 xff08 rules xff09 构成 每条规则的形式如下 xff
  • 只声明而不定义变量

    如果想声明一个变量而不定义它 xff0c 就在变量前面添加关键字extern xff0c 而且不要显式地初始化变量 extern int i 声明i而非定义i extern int j 61 0 定义 int k 声明并且定义 注意 xff
  • vector 与 智能指针使用注意事项

    看以下代码 xff0c 执行时会有什么问题 xff1f include lt vector gt include lt stdio h gt include lt stdlib h gt include lt memory gt class
  • SystemV 共享内存(一)—— 共享内存的创建与释放(shmget / shmctl)

    匿名管道和命名管道都是基于文件 的进程间通信 xff0c SystemV方案是在OS内核层面 专门为进程间通信设计的一个方案 xff0c 然后通过系统调用 xff08 system call xff09 给用户提供通信接口 SystemV方