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_CREATIPC_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;
}

  • 既然有挂载,也就应该有取消挂载 

        相应的接口为shmdtdt是detach的缩写

总结

         共享内存的特征:由于共享内存,当写进程不再向内存中写数据的时候,读进程还是会一直从内存中读数据,共享内存并不提供进程间通信的同步机制,这一点不同于管道通信,这是它的缺点。

        然而,正因为共享内存的缘故,当写进程向内存中写完数据后,读进程可以立马从内存中读取到数据,这个过程又不同于管道通信,因为管道通信是不断的拷贝,因此,共享内存的通信方式却是最快的通信方式,这是它的优点。

        因为共享内存块注定这种通信方法无法提供通信同步机制,因此,可以在共享内存通信的基础上,提供一个管道,利用管道来同步、利用共享内存来通信。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于谱聚类的多模态多目标浣熊优化算法(MMOCOA-SC)求解ZDT1-ZDT4,ZDT6和工程应用--盘式制动器优化,MATLAB代码

一、MMOCOA-SC介绍 基于谱聚类的多模态多目标浣熊优化算法&#xff08;Multimodal Multi-Objective Coati Optimization Algorithm Based on Spectral Clustering&#xff0c;MMOCOA-SC&#xff09;是2024年提出的一种多模态多目标优化算法&#xff0c;该算法的核心在于使用谱…

Gmsh有限元网格剖分(Python)---点、直线、平面的移动

Gmsh有限元网格剖分(Python)—点、直线、平面的移动和旋转 最近在学习有限元的网格剖分算法&#xff0c;主要还是要参考老外的开源Gmsh库进行&#xff0c;写一些博客记录下学习过程&#xff0c;方便以后回忆嘞。 Gmsh的官方英文文档可以参考&#xff1a;gmsh.pdf 但咋就说&a…

Go C编程 第6课 无人机 --- 计算旋转角

旋转的秘密---认识角度 rt、lt命令学习 goc电子课程 一、编程步骤 第一步 第二步 第三步 第四步 二、画“四轴无人机” &#xff08;一&#xff09;、画第一根机轴 &#xff08;二&#xff09;、画第二根机轴 &#xff08;三&#xff09;、画完整的无人机 三、画“多轴无人…

Java中以某字符串开头且忽略大小写字母如何实现【正则表达式(Regex)】

第一种思路是先将它们都转换为小写或大写&#xff0c;再使用String类的startsWith()方法实现: 例如&#xff0c;如下的二个示例&#xff1a; "Session".toLowerCase().startsWith("sEsSi".toLowerCase()); //例子之一//例子之二String str "Hello Wo…

虚拟机桥接模式网络连接不上解决方法

可能是桥接模式自动配置网络地址的时候没配好&#xff0c;自己手动配置一下。先看看windows里的wifi的ip 把虚拟机的网络设置打开ipv4把地址、子网掩码、网关输进去&#xff0c;然后再连接

频繁拿下定点,华玉高性能中间件迈入商业化新阶段

伴随着智能驾驶渗透率的快速增长&#xff0c;中国基础软件市场开始进入黄金窗口期。 近日&#xff0c;华玉通软&#xff08;下称“华玉”&#xff09;正式获得某国内头部轨道交通产业集团的智能化中间件平台定点项目。这将是华玉在基础软件领域深耕和商业化发展过程中的又一重…

Java:188 基于springboot妇幼健康管理系统

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本妇幼健康管理系统分为管理员、用户、医生三个权限。 管理员可以管理用户、医生的基本信息内容&#xff0c;可以管理药物信息以及患者预约信息等操作…

使用Excel制作通达信自定义“序列数据“

序列数据的视频教程演示 Excel制作通达信自定义序列数据 1.序列数据的制作方法&#xff1a;删掉没有用的数据&#xff08;行与列&#xff09;和股代码格式处理&#xff0c;是和外部数据的制作方法是相同&#xff0c;自己上面看历史博文。只需要判断一下&#xff0c;股代码跟随的…

计算机网络概要与习题

第1章 概论 1、计算机网络 2、互联网 3、计算机网络体系结构 分层模型 OSI/RM 7层模型 TCP/IP 5层模型 协议、PDU、SDU、SAP等术语 数据封装&#xff08;计算&#xff09; 第2章 数据通信基础 1、数据通信系统组成 2、主要性能指标 数据传输速率 码元速率 时延 …

微信小程序-基于Vant Weapp UI 组件库的Area 省市区选择

Area 省市区选择&#xff0c;省市区选择组件通常与 弹出层 组件配合使用。 areaList 格式 areaList 为对象结构&#xff0c;包含 province_list、city_list、county_list 三个 key。 每项以地区码作为 key&#xff0c;省市区名字作为 value。地区码为 6 位数字&#xff0c;前两…

每天40分玩转Django:Django静态文件

Django静态文件 一、今日学习内容概述 学习模块重要程度主要内容静态文件配置⭐⭐⭐⭐⭐基础设置、路径配置CDN集成⭐⭐⭐⭐⭐CDN配置、资源优化静态文件处理⭐⭐⭐⭐压缩、版本控制部署优化⭐⭐⭐⭐性能优化、缓存策略 二、基础配置 # settings.py import os# 静态文件配置…

Python数据处理——re库与pydantic的使用总结与实战,处理采集到的思科ASA防火墙设备信息

目录 Python正则表达式re库的基本用法 引入re库 各函数功能 总结 使用方法举例 正则表达式语法与书写方式 正则表达式的常用操作符 思科ASA防火墙数据 数据1 数据2 书写正则表达式 Python中pydantic的使用 导入基础数据模板 根据数据采集目标定义Pydantic数据类型…

「Python数据科学」标量、向量、矩阵、张量与多维数组的辨析

引言 在数据科学中&#xff0c;有很多概念&#xff0c;其中&#xff0c;最容易搞混的就是标量、向量、矩阵、张量了。具体到这些概念的落地实现&#xff0c;又与多维数组有着密不可分的联系。 本文就来尝试对这些概念进行简要地梳理&#xff0c;从而更加清晰地理解这些概念及…

iOS开发代码块-OC版

iOS开发代码块-OC版 资源分享资源使用详情Xcode自带代码块自定义代码块 资源分享 自提&#xff1a; 通过网盘分享的文件&#xff1a;CodeSnippets 2.zip 链接: https://pan.baidu.com/s/1Yh8q9PbyeNpuYpasG4IiVg?pwddn1i 提取码: dn1i Xcode中的代码片段默认放在下面的目录中…

第十七届山东省职业院校技能大赛 中职组“网络安全”赛项任务书正式赛题

第十七届山东省职业院校技能大赛 中职组“网络安全”赛项任务书-A 目录 一、竞赛阶段 二、竞赛任务书内容 &#xff08;一&#xff09;拓扑图 &#xff08;二&#xff09;模块A 基础设施设置与安全加固(200分) &#xff08;三&#xff09;B模块安全事件响应/网络安全数据取证/…

Git(11)之log显示支持中文

Git(11)之log显示支持中文 Author&#xff1a;Once Day Date&#xff1a;2024年12月21日 漫漫长路有人对你微笑过嘛… 参考文档&#xff1a;GIT使用log命令显示中文乱码_gitlab的log在matlab里显示中文乱码-CSDN博客 全系列文章可查看专栏: Git使用记录_Once_day的博客-CSD…

rabbitmq相关使用

使用rabbitmq实现异步解耦 使用步骤&#xff1a; 1、pom依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency> 2、yml配置文件 spring:rabbitmq:host: 12…

oracle linux8.10+ oracle 23ai安装

介质准备&#xff1a; 数据库23ai https://edelivery.oracle.com 上述网站下载基础版本&#xff0c;本次未使用。 本次是安装了带补丁的版本&#xff1a; Database Release Update 23.6.0.24.10 GoldImage表示带补丁用于直接安装的软件包 查找888.1对应Primary Note for …

使用helm安装canal-server和canal-admin

1.前置条件&#xff1a; 需要电脑有helm kubectl 如果没有的话需要安装环境 2.需要拉取canal-server和canal-admin镜像 拉取镜像的时候可能存在拉取不下来的情况&#xff0c;需要配置&#xff1a; /etc/docker/daemon.json {"registry-mirrors": ["https://do…

使用ForceBindIP绑定应用到指定IP

前言 使用ForceBindIP工具&#xff0c;用户可以轻松地将特定应用程序绑定到指定的IP地址&#xff0c;从而确保应用程序的网络连接通过指定的网络适配器进行。通过在命令提示符下运行ForceBindIP并指定IP地址和应用程序的完整路径&#xff0c;用户能够控制应用程序的网络流量&a…