[linux]进程间通信(IPC)———共享内存(shm)(什么是共享内存,共享内存的原理图,共享内存的接口,使用演示)

一、什么是共享内存

 共享内存区是最快的(进程间通信)IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。注意:共享内存没有进行同步与互斥!共享内存不会自动销毁,要手动销毁。

二、 共享内存的原理图

三、共享内存的接口(什么用)

ftok

功能:生成一个key,key是shmget第一个参数,这个key是一个约定的数,让不同的进程通过key找到同一份资源,不用再进入内存查找。

头文件

#include <sys/types.h>
#include <sys/ipc.h>
原型
key_t ftok(const char *pathname, int proj_id);
参数

pathname:一个路径字符串,可以随便给

proj_id:一个int数据,可以随便给

返回值:返回key

shmget

功能:用来创建共享内存

头文件

#include <sys/ipc.h>
#include <sys/shm.h>
原型
int shmget(key_t key, size_t size, int shmflg);
参数
key:这个共享内存段名字,这个key是一个约定的数,让不同的进程通过key找到同一份资源
size:共享内存的大小(一般取 n * 1024)
shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的

主要用这两个:

IPC_EXCL:不存在共享内存就创建,存在就使用现有的

IPC_EXCL:不存在共享内存就创建,存在就报错,保证创建的共享内存是新的

返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1

shmat

功能:将共享内存段连接到进程地址空间

头文件

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

原型
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数
shmid: 共享内存标识,shmget的返回值
shmaddr:指定连接的地址
shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1

说明:
shmaddr为NULL,核心自动选择一个地址
shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr - (shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表示连接操作用来只读共享内存

shmdt

功能:将共享内存段与当前进程脱离

头文件

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

原型
int shmdt(const void *shmaddr);
参数
shmaddr: 由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段,删除共享内存用shmctl

shmctl

功能:用于控制共享内存

头文件

 #include <sys/ipc.h>
 #include <sys/shm.h>
原型
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
shmid:由shmget返回的共享内存标识码
cmd:将要采取的动作(有三个可取值)

  1. PC STAT 把shmid ds结构中的数据设置为共享内存的当前关联值
  2. IPC SET 在进程有足够权限的前提下,把共享内存的当前关联值设置为shmid ds数据结构中给出的值
  3. IPC RMID 删除共享内存段

buf:指向一个保存着共享内存的模式状态和访问权限的数据结构,一般设为nullptr
返回值:成功返回0;失败返回-1

 四、使用演示

使用代码创建一个共享内存, 支持两个进程进行通信

 进程A 向共享内存当中写 “i am process A”

 进程B 从共享内存当中读出内容,并且打印到标准输出

 使用到的linux的一些指令

ipcs -m:查看共享内存的消息

ipcrm -m shmid:删除共享内存标识码为shmid的共享内存

监视脚本

while :; do ipcs -m; sleep 1; done
功能:每隔一秒打印一次共享内存消息

shm.hpp

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string>
#include <cstring>
#include <iostream>
#include <unistd.h>using namespace std;const string pathname = "/home/lwj/code11";
const int proj_id = 0x112233;
const int size = 4096;
key_t Getkey()
{int key = ftok(pathname.c_str(), proj_id);if(key < 0){perror("ftok");exit(-1);}return key;
}char* gethex(int x)
{char s[1024];sprintf(s, "0x%x", x);return s;}

processA.cc

#include "shm.hpp"
int main()
{key_t key = Getkey();cout << "获取key: " << gethex(key) << endl;sleep(10);//获取shmidint shmid = shmget(key, size, IPC_CREAT | IPC_EXCL | 0644);cout << "创建shm, 获取shmid: " << shmid << endl; if(shmid < 0){cerr << "shmget fail" << endl;exit(-1);};sleep(10);//连接shmcout << "连接shm" << endl; char* s = (char*)shmat(shmid, nullptr, 0);sleep(10);//通信cout << "写消息" << endl;string str = "i am process A";int i = 0;for (auto e : str){s[i] = e;i++;}s[i] = '\0';//断开shmsleep(10);cout << "断开shm" << endl; shmdt(s);sleep(10);//销毁shmcout << "销毁shm" << endl; shmctl(shmid, IPC_RMID, nullptr);return 0;
}

processB.cc

#include "shm.hpp"
int main()
{key_t key = Getkey();cout << "获取key: " << gethex(key) << endl;sleep(5);// 获取shmidint shmid = shmget(key, size, IPC_CREAT);cout << "创建shm, 获取shmid: " << shmid << endl; if(shmid < 0){cerr << "shmget fail" << endl;exit(-1);}// 连接shmcout << "连接shm" << endl;char *s = (char *)shmat(shmid, nullptr, 0);sleep(5);// 通信cout << "读消息: " << s << endl;// 断开shmsleep(10);cout << "断开shm" << endl;shmdt(s);sleep(10);// 销毁shmcout << "销毁shm" << endl;shmctl(shmid, IPC_RMID, nullptr);return 0;
}

Makefile

.PHNOY:all
all:processA processBprocessA:progressA.ccg++ -o $@ $^ -std=c++11
processB:progressB.ccg++ -o $@ $^ -std=c++11.PHONY:clean
clean:rm -f processA processB

演示效果视频链接:

shm演示视频-CSDN直播

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

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

相关文章

【QT QML】软件打包,生成安装包

一、版本 Desktop 5.15.2 MinGW 64-bit二、打包 1. 编译Release版本 2. 在工程目录下找到Realse文件夹 3. 拷贝文件 ***-Desktop_Qt_5_15_2_MinGW_64_bit-Release - release - xxx.exe到一个新文件夹中 4. 开启相应打包工具&#xff08;根据自己的编译器和版本选择&#xff0…

w29pikachu-ssrf实例

SSRF简介 SSRF是服务器端请求伪造 危害&#xff1a; 1.可以对服务器所在内网、本地进行端口扫描&#xff0c;获取一些服务的信息等 2.目标网站本地敏感数据的读取 3.内外网主机应用程序漏洞的利用 4.内外网web站点漏洞的利用 ssrf常用的相关协议&#xff1a; gopher://: 发…

QT基本组件

四、基本组件 Designer 设计师&#xff08;重点&#xff09; Qt包含了一个Designer程序&#xff0c;用于通过可视化界面设计开发界面&#xff0c;保存文件格式为.ui&#xff08;界面文件&#xff09;。界面文件内部使用xml语法的标签式语言。 在Qt Creator中创建文件时&#xf…

3.测试教程 - 基础篇

文章目录 软件测试的生命周期软件测试&软件开发生命周期如何描述一个bug如何定义bug的级别bug的生命周期如何开始第一次测试测试的执行和BUG管理产生争执怎么办&#xff08;处理人际关系&#xff09; 大家好&#xff0c;我是晓星航。今天为大家带来的是 测试基础 相关的讲解…

pclpy 可视化点云(多窗口可视化、单窗口多点云可视化)

pclpy 可视化点云&#xff08;多窗口可视化、单窗口多点云可视化&#xff09; 一、算法原理二、代码三、结果1.多窗口可视化结果2.单窗口多点云可视化 四、相关数据五、问题与解决方案1.问题2.解决 一、算法原理 原理看一下代码写的很仔细的。。目前在同一个窗口最多建立2个窗…

亿道丨三防平板丨加固平板丨三防加固平板丨改善资产管理

库存资产管理中最重要的部分之一是准确性&#xff1b;过时的库存管理技术会增加运输过程中人为错误、物品丢失或纸张损坏的风险。如今随着三防平板电脑的广泛使用&#xff0c;库存管理也迎来了好帮手&#xff0c;通过使用三防平板电脑能够确保库存管理、数据存储和记录保存的准…

《幻兽帕鲁》值得入手吗?MACOS 游戏 幻兽帕鲁MAC可以玩吗?

最近&#xff0c;一款名为《幻兽帕鲁》的游戏备受玩家瞩目。在追寻开放且多样化游戏体验的今天&#xff0c;《幻兽帕鲁》以其独特的玩法和世界观吸引了大批游戏爱好者。尽管游戏表面上看起来像是方舟的萌系版本&#xff0c;但其独特的特色却令人耳目一新。 首先&#xff0c;让我…

OceanBase数据迁移-从MySQL导入数据到OceanBase

把MySQL中的数据导入到OceanBase&#xff0c;分几个步骤&#xff1a; 1.准备一份MySQL测试数据集2.使用mydumper工具导出MySQL数据3.使用myloader工具导入到OceanBase4.验证测试数据集在OceanBase下的执行情况 1.准备一份MySQL测试数据集 1.1.从github下载mysql测试数据集&a…

React 模态框的设计(二)

自定义组件是每个前端开发者必备的技能。我们在使用现有框架时难免有一些超乎框架以处的特别的需求&#xff0c;比如关于弹窗&#xff0c;每个应用都会用到&#xff0c;但是有时我们使用的框架中提供的弹窗功能也是功能有限&#xff0c;无法满足我们的应用需求&#xff0c;今天…

C#串口 Modbus通讯工具类

一、安装Modbus包 二、创建modbushelper类 1、打开串口 public bool IfCOMOpend; //用于实例内的COM口的状态 public SerialPort OpenedCOM;//用于手动输入的COM转成SERIAL PORT /// <summary> /// 打开串口 /// </summary> /// <param name="COMname&quo…

链表之“无头单向非循环链表”

目录 ​编辑 1.顺序表的问题及思考 2.链表 2.1链表的概念及结构 2.2无头单向非循环链表的实现 1.创建结构体 2.单链表打印 3.动态申请一个节点 3.单链表尾插 4.单链表头插 5.单链表尾删 6.单链表头删 7.单链表查找 8.单链表在pos位置之前插入x 9.单链表删除pos位…

糖尿病性视网膜病变(DR)的自动化检测和分期

糖尿病性视网膜病变&#xff08;DR&#xff09;的自动化检测和分期 提出背景DR的阶段及其特征 历年解法计算机视觉方法多分类方法 新的解法深度学习方法迁移学习大模型多模型集成全流程分析 总结特征1&#xff1a;图像分割特征2&#xff1a;疾病分级特征3&#xff1a;治疗建议生…

Radware Alteon负载均衡-基于域名的七层负载均衡

Radware Alteon作为一款高性能的负载均衡器&#xff0c;其基于域名的七层负载均衡功能为众多企业提供了灵活、高效的解决方案。 该案例实现如下需求&#xff1a;客户端访问服务器&#xff0c;当访问域名为www.iisstart.com时&#xff0c;默认访问Server1&#xff0c;当配置七层…

Sqoop 入门基础

简介 Sqoop&#xff08;SQL to Hadoop&#xff09;是一个开源工具&#xff0c;用于在关系型数据库和Hadoop之间传输数据。它提供了一种快速高效的方式&#xff0c;将数据从关系型数据库导入到Hadoop集群进行分析&#xff0c;并支持将Hadoop集群中的数据导出到关系型数据库中。本…

MAC M1安装vmware和centos7虚拟机并配置静态ip

一、下载vmware和centos7镜像 1、VMWare Fusion 官网的下载地址是&#xff1a;下载地址 下载好之后注册需要秘钥&#xff0c;在官网注册后使用免费的个人秘钥 2、centos7 下载地址&#xff1a; https://biosyxh.cn:5001/sharing/pAlcCGNJf 二、虚拟机安装 直接将下…

学生成绩管理系统(C语言课设 )

这个学生成绩管理系统使用C语言编写&#xff0c;具有多项功能以方便管理学生信息和成绩。首先从文件中读取数据到系统中&#xff0c;并提供了多种功能&#xff08;增删改查等&#xff09;选项以满足不同的需求。 学生成绩管理系统功能: 显示学生信息增加学生信息删除学生信息…

使用 C++23 协程实现第一个 co_await 同步风格调用接口--Qt计算文件哈希值

C加入了协程 coroutine的特性&#xff0c;一直没有动手实现过。看了网上很多文章&#xff0c;已经了解了协程作为“可被中断和恢复的函数”的一系列特点。在学习过程中&#xff0c;我发现大多数网上的例子&#xff0c;要不就是在main()函数的控制台程序里演示yeild,await, resu…

Jmeter基础(2) 目录介绍

目录 Jmeter目录介绍bin目录docsextrasliblicensesprintable_docs Jmeter目录介绍 在学习Jmeter之前&#xff0c;需要先对工具的目录有些了解&#xff0c;也会方便后续的学习 bin目录 examplesCSV目录中有CSV样例jmeter.batwindow 启动文件jmeter.shMac/linux的启动文件jmete…

《最新出炉》系列初窥篇-Python+Playwright自动化测试-19-处理鼠标拖拽-中篇

1.简介 上一篇中&#xff0c;主要是介绍了拖拽的各种方法的理论知识以及实践&#xff0c;今天宏哥讲解和分享一下划取字段操作。例如&#xff1a;需要在一堆log字符中随机划取一段文字&#xff0c;然后右键选择摘取功能。 2.划取字段操作 划取字段操作就是在一段文字中随机选…

分布式id实战

目录 常用方式 特征 潜在问题 信息安全 高性能 UUID 雪花算法 数据库生成 美团Leaf方案 Leaf-segment 数据库方案 Leaf-snowflake 方案 常用方式 uuid雪花算法数据库主键 特征 全局唯一趋势递增信息安全 潜在问题 信息安全 如果id连续递增, 容易被爬虫, 批量下…