Linux:SystemV通信
目录
一、System V通信
二、共享内存
代码板块
总结
三、信号量
信号量理论
信号量接口
一、System V通信
System V IPC(inter-process communication),是一种进程间通信方式。其实现的方法有共享内存、消息队列、信号量这三种机制。
二、共享内存
进程间通信的本质就是让不同进程看到同一份资源,比如匿名管道是利用了父子进程之间继承机制,命名管道是利用路径找到同一个文件。
共享内存本质也是让不同进程看到同一份资源。
学习进程的通信方法,本质都是在学习是如何让不同进程使用到同一份资源的。
- 共享内存机制
第一步,由操作系统在内存中开辟内存空间。
第二步:操作系统把共享内存的地址通过页表映射到进程地址空间中。
另一个进程同样如此。
进程通过这块内存通信,通信完毕后,还有移除映射、释放共享内存等步骤。
- 共享内存的细节
实际上,会有多个进程都采用共享内存的方式通信,因此会有多个被开辟的小内存空间,用来通信,操作系统同样要对这些个共享内存作管理,同样要标识唯一的共享内存,这个关键字在Linux下的类型命名为key_t。
于是,我们要理解共享内存的本质,就是要理解,两个进程究竟是通过怎样的方式拿到同一个key_t的。
先来认识一下,Linux下创建共享内存的系统调用接口。
man 2 shmget
第一个参数,key_t key ,这个参数就是用来标识唯一的共享内存空间的,由用户传入,并不是由操作系统指定。
原因:当一个进程想要和另一个进程通信,A进程是无法得知B进程的一切信息的,它只能自己申请创建一块共享内存空间,然后想办法让B进程也能访问到这个特定的内存空间,但是在操作系统看来,它管理这多个这样的内存空间,操作系统是不知道A和B是想要通信的,也就无法将这个唯一标识传给B进程。
因此这个参数key只能由用户设置。
但是,直接设置这样一个标识符可能会大概率和其他共享内存空间的标识符冲突,因此有专门的一个函数,可以根据用户设置的字符串来生成唯一且随机的一个标识符。
man 3 ftok
想要通信的两个进程,到时候在源代码中约定一样的字符串,根据这个函数生成共享内存空间的唯一标识符,由其中一个进程向操作系统申请创建这块内存空间,至此,两个进程都能拿到同一块共享内存空间了,这便是System V共享内存的实质。
第二个参数,指定共享内存空间的大小
第三个参数,用来指定特殊标志,传参选项有IPC_CREAT、IPC_EXCL,
传参形式有三种:
只传IPC_CREAT:如果要创建的共享内存空间不存在,就创建它,如果已经存在,则直接使用它。
只传IPC_EXCL:无意义。
传参IPC_CREAT | IPC_EXCL: 如果要创建的共享内存空间不存在,就创建它,如果已经存在,则报错!!
代码板块
- 1.先实现获取key
//可以随机定义
const char* pathname = "/home/utocoo/Desktop/linux/241221";
const int pri_id = 0x67;
//获取key
key_t CreatKeyOrDie()
{key_t key = ftok(pathname,pri_id);if(key < 0){cerr << "ftok error,errno->" << errno<<"->" << strerror(errno) << endl;exit(1);}return key;
}
- 2.再根据key申请共享内存
//根据Key申请共享内存
int CreatShmOrDie(key_t key,size_t size,int flag)
{int shmid = shmget(key,size,flag);if(shmid < 0){cerr << "shmget error,errno->" << errno << "->" << strerror(errno) << endl;exit(2);}return shmid;
}
然而,在通信的用户看来,创建共享内存时,只需要指定key和内存大小即可,所有可以把这个函数再次封装。
并且对于要创建内存的进程而言,比如A进程,创建内存时,如果不存在就创建,如果存在则报错;而对B进程而言,如果内存已经存在,只需要获取它的shmid即可。
//A进程创建
int CreatShm(key_t key,size_t size)
{CreatShmOrDie(key,size,IPC_CREAT | IPC_EXCL | 0666);
}
//B进程不用再创建,只需要获取即可
int GetShm(key_t key,size_t size)
{CreatShmOrDie(key,size,IPC_CREAT);
}
再来认识一下创建共享内存空间函数shmget的返回值,int shmid,这个返回值同样可以标识唯一的一块内存空间,它和另一个标识符key又有什么样的关联?
key这个关键字,是在内核级别,帮助操作系统标识唯一的共享内存空间。
而shmget的返回值,是帮助用户来管理这块内存空间,作为用户来讲,往往是通过shmid来使用各种各样的接口。
- 释放共享内存空间
进程退出后,如果用户不主动释放申请的共享内存,那么这块内存的生命周期是一直跟随着操作系统的,只有重启才会重新初始化这块内存。
释放共享内存的接口为shmctl+特定参数
man 2 shmctl
第三个参数的类型就是操作系统用来描述共享内存的结构体,cmd的取值范围在man手册中也有说明。
//释放共享内存
void DeleteShm(int shmid)
{int r = shmctl(shmid,IPC_RMID,nullptr);if(r < 0){cerr << "delete shm error,errno->" << errno << "->" << strerror(errno) << endl;exit(3);}else {cout << "delete shm->" << shmid << "success" << endl;}
}
关于释放共享内存,上面介绍的是在代码中我们利用系统调用接口实现,也可以在命令行中通过指令完成释放。
ipcs指令查看SystemV通信的所有介质。
ipcs
ipcs -m则只查看所有的共享内存。
ipcs -m
ipcrm -m 指定的shmid则在命令行中删除指定shmid的共享内存。
ipcrm -m shmid
- 将内存空间挂载或者说映射到进程的虚拟地址空间中
所用到的接口是shmat,
第二个参数,shmaddr用来指定要将指定shmid的共享内存映射到虚拟地址空间的哪个地方,第三个参数shmflag默认传0即可,特殊用途可以传特殊参数,这些在man手册中均有说明。
需要说明的是返回值
shmat会返回虚拟地址空间段地址,否则返回(void*)-1
//映射到进程上面
void* ShmAttah(int shmid)
{char* addr = (char*)shmat(shmid,nullptr,0);if((int64_t)addr == -1){cerr << "ShmAttach error,errno->" << errno << "->" << strerror(errno) << endl;return nullptr;}return addr;
}
- 既然有挂载,也就应该有取消挂载
相应的接口为shmdt,dt是detach的缩写,
总结
共享内存的特征:由于共享内存,当写进程不再向内存中写数据的时候,读进程还是会一直从内存中读数据,共享内存并不提供进程间通信的同步机制,这一点不同于管道通信,这是它的缺点。
然而,正因为共享内存的缘故,当写进程向内存中写完数据后,读进程可以立马从内存中读取到数据,这个过程又不同于管道通信,因为管道通信是不断的拷贝,因此,共享内存的通信方式却是最快的通信方式,这是它的优点。
因为共享内存块注定这种通信方法无法提供通信同步机制,因此,可以在共享内存通信的基础上,提供一个管道,利用管道来同步、利用共享内存来通信。
三、信号量
信号量理论
- 同步和互斥。
互斥机制:像共享内存这样的通信方式中,写进程在写的过程中,如果读进程可以随时随地的读,最终可能造成数据不一致的情况,因此,为了避免这种数据不一致的情况,引入互斥机制,让一份资源只能由一个进程在享用,另一个进程想要享用,必须要排队等待。
同步机制:引入互斥机制后,个别进程可能长时间享用一份资源,导致其他进程在一段时间内都无法享用该资源,因此,引入同步机制,来解决个别进程长时间占用资源的问题。
- 临界资源
被保护的资源,进程之间互斥访问的资源,称为临界资源。
用来访问临界资源的代码,被称为临界区,同时,其他代码被称为非临界区,而保护公共资源是互斥访问本质就是在保护临界区,显然,如何保护临界区,是由程序员来实现。
- 什么是操作的原子性
对临界资源的操作,只有两种状态,要么还没开始访问,要么已经结束访问。
- 临界资源的访问
将临界资源,也就是一块内存,视为一个整体,这个时候一个进程访问,其他进程必须等待,考虑到效率问题,将这块内存划分为多个小内存,比如100MB的共享内存划分为多个4KB的小内存,让多进程互斥的访问小内存,可以提高效率。
这种设计需要满足:
1.被划分的小内存数量是有限的,因此,必须限制多进程数量,只允许一定数量的进程访问。
2.如何合理分配小内存给多个进程。
- 什么是信号量
“信号量”往往是在说信号量机制,我们已经知道信号量机制是SystemV通信方式的一种,是用来帮助进程通信的,那么要如何理解。
信号量本质是一个计数器,用来表述临界资源的数量,计数器有加减操作来表示临界资源数量的变化,某一个进程对这个计数器可能做加或者减操作,造成计数器值的改变要求其他进程也能看到,符合“让不同的进程看到同一份资源”这一原理,因此,信号量资源本质也是共享资源。
- 信号量不能用整型变量表示
一是因为整型变量不能被共享,二是因为整型变量的加减操作不满足原子性。
- 信号量机制
进程在访问临界资源的时候,
通常是先要申请资源,信号量做减法,也称P操作。
申请成功则表示对资源的预订,不一定立刻访问,申请失败表示资源数不够,进程必须等待
资源访问完毕后进程释放资源,信号量做加法,也称V操作。
PV操作就是进程在保护临界资源的过程。
- 信号量本身就是临界资源
信号量本身就是临界资源,必须要有申请、释放信号量的过程。
信号量接口
- 申请信号量
semget。
- 释放信号量
semctl。
- PV操作
semop
相关文章:

Linux:SystemV通信
目录 一、System V通信 二、共享内存 代码板块 总结 三、信号量 信号量理论 信号量接口 一、System V通信 System V IPC(inter-process communication),是一种进程间通信方式。其实现的方法有共享内存、消息队列、信号量这三种机制。 …...

C#上位机通过CAN总线发送bin文件
让gpt生成一段代码用来把bin文件通过can总线发出去 c#代码还是比较强大的,各种功能基本都是一两行代码就实现了,这里记录一下对这个代码的理解和解读 主要代码如下,传入bin文件的地址即可将其从指定的can通道发送出去: public …...

CV 图像处理基础笔记大全(超全版哦~)!!!
一、图像的数字化表示 像素 数字图像由众多像素组成,是图像的基本构成单位。在灰度图像中,一个像素用一个数值表示其亮度,通常 8 位存储,取值范围 0 - 255,0 为纯黑,255 为纯白。例如,一幅简单的…...

2-Kbengine+Unity3D多人在线游戏DEMO源码架构分析
2-Kbengine+Unity3D多人在线游戏DEMO源码架构分析 目录 一、服务器端 1、编写并生成我们的服务器端和客户端通用的游戏协议 2、 认识Entity实体 3、 官方DEMO-kbengine_demos_assets分析 二、 客户端...

Vue.js组件开发-如何实现表头搜索
在Vue.js组件开发中,实现表头搜索通常涉及在表格组件的表头添加输入框,并让用户能够输入搜索关键字来过滤表格数据。 以下是一个使用Element UI的el-table组件实现表头搜索的示例: 一、准备阶段 确保Element UI已安装: 确保…...

lerna使用指南
lerna版本 以下所有配置命令都是基于v8.1.9,lerna v5 v7版本差别较大,在使用时,注意自身的lerna版本。 lerna开启缓存及缓存配置 nx缓存是v5版本以后才有的,小于该版本的无法使用该功能。 初始化配置 缓存配置文件nx.json&am…...

spark,读取和写入同一张表问题
读取a表,写入a表 1.写入的是分区表,不报错 2.读取上来之后,创建为临时视图temp,然后先写入a表,再使用temp,就会报错 解决办法:可以先使用temp,再写入a表 3.写入的不是分区表&…...

iOS - TLS(线程本地存储)
从源码中,详细总结 TLS (Thread Local Storage) 的实现: 1. TLS 基本结构 // TLS 的基本结构 struct tls_data {pthread_key_t key; // 线程本地存储的键void (*destructor)(void *); // 清理函数 };// 自动释放池的 TLS class Autorelease…...

node.js项目依赖关系分析工具 Depazer 的使用
node.js项目依赖关系分析工具 Depazer 的使用 Depazer 是一个用于 分析和可视化 Node.js 项目依赖关系 的工具。它可以帮助开发者快速了解项目的依赖结构、模块关系,以及可能存在的问题,从而优化代码架构和依赖管理。 功能特点 依赖关系分析࿱…...

QT 如何禁止QComboBox鼠标滚轮
一般情况下,QComboBox会相应鼠标的滚轮事件,即当鼠标停靠在QComboBox上方时,滚动鼠标滚轮,QComboBox的选项会发生切换。但这或许并不是我们希望所出现的,尤其是当QComboBox嵌入在QScrollArea中时,用户只是想…...

理解CPU负载与使用率
目录 CPU使用率 CPU负载 CPU使用率 定义:就像看一个工人干活的时间占他上班时间的比例。比如工人上班8小时,实际干活6小时,干活时间占比就是68100%75%。对于CPU,单核的看它被占用的时间占总时间的比例,多核的就把每个…...

浅谈计算机网络01 | SDN数据平面
浅谈基本云架构 一、计算机网络数据平面的基础理论1.1 数据平面与控制平面的区分1.1.1 两者功能差异1.1.2 协同工作机制 1.2 数据平面在网络架构中的位置与角色1.2.1 与各网络层次的关系1.2.2 对网络整体性能的影响 二、数据平面的关键技术原理2.1 转发技术2.1.1 基于目的地转发…...

《Java开发手册》核心内容
文章目录 引言I 编程规约II 异常日志III 单元测试 :IV 安全规约 :V MySQL数据库:VI 工程结构 :VII 设计规约 :引言 手册的愿景是提升代码质量和开发效率,通过规范化的编码实践来减少错误和提高系统的稳定性。 I 编程规约 命名风格:规定了命名的一致性和规范性,避免使…...

采用海豚调度器+Doris开发数仓保姆级教程(满满是踩坑干货细节,持续更新)
目录 一、采用海豚调度器+Doris开发平替CDH Hdfs + Yarn + Hive + Oozie的理由。 1. 架构复杂性 2. 数据处理性能 3. 数据同步与更新 4. 资源利用率与成本 6. 生态系统与兼容性 7. 符合信创或国产化要求 二、ODS层接入数据 接入kafka实时数据 踩坑的问题细节 三、海…...

通过将模型权重的矩阵表示为低秩矩阵,可以减少需要调整的参数数量,通俗易懂的解释,不懂你爬网线打我
通过将模型权重矩阵表示为低秩矩阵,可以减少需要调整的参数数量,原因在于低秩矩阵的结构本身就比高秩矩阵更“紧凑”,即它们需要的独立参数更少。具体来说,低秩矩阵的结构可以通过减少模型的自由度(独立参数的数量&…...

Java并发编程——线程池(基础,使用,拒绝策略,命名,提交方式,状态)
我是一个计算机专业研0的学生卡蒙Camel🐫🐫🐫(刚保研) 记录每天学习过程(主要学习Java、python、人工智能),总结知识点(内容来自:自我总结网上借鉴࿰…...

DilateFormer: Multi-Scale Dilated Transformer for Visual Recognition 中的空洞自注意力机制
空洞自注意力机制 文章目录 摘要1. 模型解释1.1. 滑动窗口扩张注意力1.2. 多尺度扩张注意力 2. 代码3. 流程图3.1. MultiDilatelocalAttention3.2. DilateAttention3.3. MLP 摘要 本文针对DilateFormer中的空洞自注意力机制原理和代码进行详细介绍,最后通过流程图梳…...

二十三种设计模式-适配器模式
适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将不兼容的接口转换成客户端期望的接口,从而使原本因接口不匹配而不能一起工作的类可以协同工作。以下是关于适配器模式的详细介绍: 一、定义及作用 定义&am…...

复用类(2):代理、结合使用组合和继承
1 代理 第三种关系称为代理,这是继承与组合之间的中庸之道,因为我们将一个成员对象置于所要构造的类中(就像组合),但与此同时我们在新类中暴露了该成员对象的所有方法(就像继承)。例如ÿ…...

浅谈云计算07 | 云安全机制
云计算安全机制 一、引言二、加密技术:数据的隐形护盾三、散列机制:数据完整性的忠诚卫士四、数字签名:数据来源与真伪的鉴定专家五、公钥基础设施(PKI):信任的基石六、身份与访问管理(IAM&…...

【机器学习】零售行业的智慧升级:机器学习驱动的精准营销与库存管理
我的个人主页 我的领域:人工智能篇,希望能帮助到大家!!!👍点赞 收藏❤ 在当今数字化浪潮汹涌澎湃的时代,零售行业正站在转型升级的十字路口。市场竞争的白热化使得企业必须另辟蹊径࿰…...

深入理解 Entity、VO、QO、DTO 的区别及其在 MVC 架构中的应用
文章背景 在现代软件开发中,我们经常会接触到各种数据结构的概念,比如 Entity、VO(Value Object)、QO(Query Object)、DTO(Data Transfer Object)等。这些概念尽管看似相似ÿ…...

vue集成高德地图API实现坐标拾取功能
安装与配置: 组件 | vue-amapDescriptionhttps://elemefe.github.io/vue-amap/#/zh-cn/introduction/install简介 | vuemap/vue-amap简介https://vue-amap.guyixi.cn/zh-cn/introduction/introduction.html 我的应用 | 高德控制台高德开放平台官网控…...

Spring Boot Actuator 详细介绍
Spring Boot Actuator 详细介绍 1. 简介 Spring Boot Actuator 是 Spring Boot 提供的一个用于监控和管理应用程序的强大功能模块。它可以帮助我们了解应用程序的运行状况、指标收集、环境信息、日志级别管理等。 2. 添加依赖 2.1 在 pom.xml 中添加以下依赖: …...

联通用户管理系统(一)
#联通用户管理系统(一) 1.新建项目 如果你是windows的话,界面应该是如下的: 2.创建app python manage.py startapp app01一般情况下:我们是在pycharm的终端中运行上述指令,但是pychrm中为我们提供了工具…...

go chan底层分析
go chan底层分析 底层源码hchanmakechan 方法 环形队列阻塞机制向管道写数据流程图源码 从管道读数据流程图源码 关闭通道 底层源码 hchan type hchan struct {qcount uint // 当前队列中剩余元素个数dataqsiz uint // 环形队列长度,即可以…...

idea上git log面板的使用
文章目录 各种颜色含义具体的文件的颜色标签颜色🏷️ 节点和路线 各种颜色含义 具体的文件的颜色 红色:表示还没有 git add 提交到暂存区绿色:表示已经 git add 过,但是从来没有 commit 过蓝色:表示文件有过改动 标…...

WOA-Transformer鲸鱼算法优化编码器时间序列预测(Matlab实现)
WOA-Transformer鲸鱼算法优化编码器时间序列预测(Matlab实现) 目录 WOA-Transformer鲸鱼算法优化编码器时间序列预测(Matlab实现)预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现WOA-Transformer鲸鱼算法优化编…...

dock 制作 python环境
报错 :Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) 解决方法 配置加速地址 vim /etc/docker/daemon.json 添加以下内容 { "registry-mirror…...

2025第3周 | json-server的基本使用
目录 1. json-server是什么?2. json-server怎么用?2.1 安装2.2 创建db.json2.3 启动服务2.4 查看效果 3. 前端进行模拟交互3.1 创建demo.html3.2 创建demo.js 2025,做想做的事,读想读的书,持续学习,自律生活…...