探索共享内存:解锁并发编程的潜力

news2024/11/26 22:35:36

文章目录

  • 序言
  • shm 原理
  • 对shm的理解
  • 通过代码认识shm
  • 调用shmget方法实现

序言

system V版本
指定的一种规则(俗话说一流公司定规则,二流公司重服务,三流公司重技术).这个规则虽然有很多种(消息队列,共享内存等只是比较出名的几个).但是在内核的相关技术解决上是类似的,因为都是基于同一套标准

shm 原理

它是进程间通信的前提,必须让不同的进程看到同一份资源(这份资源由OS提供)

以父进程创建子进程为例:
在这里插入图片描述

对shm的理解

上述两个进程被加载进内存,共享同一块内存
但实际内存中,并不只存在这一对父子进程,还有其他的进程也有共享内存,所以在OS中会存在一张共享内存管理表
对上述内容的理解:
1.往后对共享内存的管理就变成了对数据结构的增删查改
在这里插入图片描述

2.共享内存具有唯一的标识,来保证第二个参与共享内存的进程看到的就是期望的那个共享内存---->怎么确定这个标识?怎么给另一个进程?
1.实现一个共享内存创建
利用shmget()函数实现在这里插入图片描述这个第一个参数类型,第一个参数代表什么意思呢?

ftok函数约定生成一个key_t的数,key_t本质是int

shmflg 即能创建,又能获取:
提供两个宏
IPC_CREAT:shm不存在,就创建,存在就获取并返回,只是读取设置0也可以(一般用于获取)
IPC_EXCL:不单独使用
IPC_EXCL | IPC_CREAT:shm 不存在就创建,存在就出错返回(一般用于创建)(主要是保证创建的共享内存是全新的)

2.识别给另一个进程 at—>attach
在这里插入图片描述

3.去掉进程的共享内存关联dt —> detach
在这里插入图片描述
页表映射部分的函数
通过页表将虚拟地址空间和物理内存的共享区进行映射

这个函数的第二个参数:

指定虚拟内存地址,但是不了解实际使用情况,所以一般为NULL

第三个参数:

不深究(实际表示写还是读,但是由权限码来控制),设为0即可

应用:

在这里插入图片描述运行查看结果:
在这里插入图片描述在sleep(5)看到了这个共享内存被server这个程序使用,所以被使用的进程数为1
当sleep结束后,程序退出,被调用进程数量就回到了0

怎么去掉这个关联的共享内存(本质就是修改页表)?
参数就是shmat的那个返回值
在这里插入图片描述
去除关联
从进程的地址空间中删除
此外,这个函数的返回值是返回一段地址空间,类似malloc的返回值

4.控制这个接口(改和查)

在这里插入图片描述
cmd参数:要做哪方面的控制,他提供了几个宏,其中使用演示:IPC_RMID(删除)
struct shmid_ds *buf参数:是OS的共享内存结构返回给上层用户的一个struct,暂时不用,设置为0

在这里插入图片描述

通过代码认识shm

通过写代码的认识共享内存

所有的 进程间通信,只有匿名管道是只允许血缘关系的进程间通信,其他进程间通信都是两个不相干进程间就能实现通信

首先两个进程之间怎么找到这个共享内存?

约定一个数字假设是1234,将这个1234在创建共享内存时就加载到struct shm结构体当中,未来要找这个共享内存只需要找这个对应的数字即可
这个数字可能与系统的共享内存的数字 冲突,所以利用内置的算法函数生成一个较低概率的数字

在这里插入图片描述ftok的演示结果
在这里插入图片描述
以下是源码:
在这里插入图片描述在这里插入图片描述
这个key是自己约定出来的

调用shmget方法实现

1.开辟共享内存,2.将shmid存入结构体内
在这里插入图片描述
结果:
在这里插入图片描述

可以看到不存在就创建全新的共享内存,存在就出错返回,(client,server里面是生成同一个shmid)
使用ipcs -m查看创建的共享内存

在这里插入图片描述
结论:

共享内存(IPC资源)的生命周期是随内核的

如何进行删除共享内存?

首先理解一下shmid和key的区别?
key只用来标识共享内存的唯一性
shmid用来操作这个共享内存
删除共享内存:
ipcrm -m shmid号

在这里插入图片描述
转16进制的方法:
在这里插入图片描述

sizeof(buf)用于限制 snprintf 函数写入数据的最大长度,以保证程序的安全性

cliet.cc
在这里插入图片描述
server.cc
在这里插入图片描述
两个进程如何知道他们在访问同一块内存?在命名管道是通过绝对路径看到同一份资源,在共享内存时通过key看到同一份资源
特殊性:共享内存没有同步机制,
由用户自己提供同步机制,(以前学过的管道实现)
server部分:
创建管道,打开管道,从管道读取
client:
打开管道,向管道内写入
在这里插入图片描述
如何,移除共享内存中的内容
对于共享内存中的数据,不需要进行实际的删除,让读的数据读完向后走,不在再能访问这个位置,就当是删除了
在这里插入图片描述
调整代码实现退出客户端和服务端后删除共享内存
unlink删除指定的文件:

在这里插入图片描述
共享内存的特点:

1.共享内存是裸露给所有的使用者的,一定要注意安全问题
2.共享内存是所有进程间通信最快的方式
3.共享内存可以提供较大的空间

在这里插入图片描述
场景应用,共享内存相比较管道,少了几次拷贝?

首先数据会进入管道,通过write函数进入管道,再从管道通过read函数进入目标进程的缓冲区.
而共享内存会省去这两步,直接通过A—>共享内存---->B的过程

IPC_STAT的使用

创建关联的时间戳

能获取这个属性,意味着一定维护(描述)了这个共享内存
即:为什么能找到同一块共享内存,他们被OS所维护

创作不易,有用请观众姥爷来个三连支持一下~~~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NIUKE SQL:进阶挑战 (下)

05 窗口函数 专用窗口函数 SQL136 每类试卷得分前3名 找到每类试卷得分的前3名,如果两人最大分数相同,选择最小分数大者,如果还相同,选择uid大者 SELECT tag,uid,ranking FROM(SELECTtag,ER.uid,ROW_NUMBER() OVER (PARTITION …

jdk8的新特征

1: jdk8中新增的方法 在jdk8中对接口进行了增强,在jdk8之前 interface 接口名{ 静态常量: 抽象方法: } 在jdk8之后 interface 接口名{ 静态常量: 抽象方法: 默认方法: 静态方法: } 2…

【IMX6ULL项目】IMX6ULL下Linux实现产测工具框架

电子产品量产测试与烧写工具。这是一套软件,用在我们的实际生产中, 有如下特点: 1.简单易用: 把这套软件烧写在 SD 卡上,插到 IMX6ULL 板子里并启动,它就会自动测试各个模块、烧写 EMMC 系统。 工人只要按…

【算法】dfs

快乐的流畅:个人主页 个人专栏:《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火,在为久候之人燃烧! 文章目录 引言一、全排列1. 决策树2. 设计代码1. 全局变量2. dfs函数3. 细节问题 二、子集解法一1. 决策树2. 设计代码…

Spring Boot:让微服务开发像搭积木一样简单!

带你一探 Spring Boot 的自动配置和 Starter POMs 的神奇之处,展示如何通过几个简单的步骤就能让你的微服务应用在云端翱翔! 文章目录 1. 引言1.1 简述Spring框架的起源与重要性1.2 阐述文章目的:深入解析Spring核心功能与应用实践2. 背景介绍…

C语言 | Leetcode C语言题解之第85题最大矩形

题目&#xff1a; 题解&#xff1a; int maximalRectangle(char** matrix, int matrixSize, int* matrixColSize) {int m matrixSize;if (m 0) {return 0;}int n matrixColSize[0];int left[m][n];memset(left, 0, sizeof(left));for (int i 0; i < m; i) {for (int j …

251 基于matlab的动态粒子群算法

基于matlab的动态粒子群算法。普通粒子群算法无法感知外界环境的变化&#xff0c;在外界环境发生改变时无法实时进行响应&#xff0c;因而缺乏动态环境寻优能力。在普通粒子群算法基本上通过增加敏感粒子得到一种动态粒子群算法&#xff0c;该算法通过实时计算敏感粒子的适应度…

Redis集群安装

将Redis安装包分别上传到3个文件夹&#xff0c;并解压缩 #编译并指定安装目录 cd /root/usr/local/redis-cluster/redis-7001/redis-6.2.6/ make make PREFIX/root/usr/local/redis-cluster/redis-7001 install # cd /root/usr/local/redis-cluster/redis-7002/redis-6.2.6/ m…

iZotope RX 11 for Mac 激活版:让您的音频焕发生机!

在追求音频完美的道路上&#xff0c;iZotope RX 11 for Mac是您的得力助手。它凭借先进的音频修复技术和丰富的音频增强工具&#xff0c;让您的音频作品焕发出前所未有的生机与活力。无论您是专业的音频工程师&#xff0c;还是业余的音乐爱好者&#xff0c;都能在这款工具中找到…

栈的讲解

栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底&#xff08;因为先进后出&#xff09;。栈中的数据元素遵守后进先出LIFO&#xff08;Last In Firs…

【Threejs进阶教程-算法篇】1.常用坐标系介绍与2d/3d随机点位算法

2d/3d随机算法 学习ThreeJS的捷径坐标系简介平面直角坐标系和极坐标系空间直角坐标系圆柱坐标系球坐标系球坐标系与直角坐标系的转换 基于坐标系系统的随机点位算法平面直角坐标系随机平面直角坐标系随机的变形 空间直角坐标系随机二维极坐标系随机圆柱坐标系随机基于Cylinderc…

Python 整数类型(int)详解:无限范围与多种进制

引言 在编程中&#xff0c;整数是最基本的数据类型之一。不同编程语言对整数的处理方式各不相同&#xff0c;这往往影响到程序的性能和开发者的选择。本文将深入探讨 Python 中的整数类型&#xff08;int&#xff09;&#xff0c;其独特的处理方式&#xff0c;以及它在日常编程…

Lambda表达式 怎么debug调试

前言 Lambda 表达式是 JDK8 的一个重要新特性&#xff0c;可以取代大部分的匿名内部类&#xff0c;写出更优雅的 Java 代码&#xff0c;尤其在集合的遍历和其他集合操作中&#xff0c;可以极大地优化代码结构。JDK 也提供了大量的内置函数式接口供我们使用&#xff0c;使得 La…

【Chrome实用命令笔记】

文章目录 Chrome实用命令笔记1、chrome基本介绍2. 打开开发者工具&#xff08;DevTools&#xff09;方法一&#xff1a;快捷键方法二&#xff1a;右键菜单方法三&#xff1a;浏览器设置 2. 开发者工具面板Elements面板Console面板Sources面板Network面板Performance面板Memory面…

C++ 数据结构算法 学习笔记(25) - 图及其企业级应用

C 数据结构算法 学习笔记(25) - 图及其企业级应用 图的故事导入 故事情节 Jack 自从买车后&#xff0c;交通出行方便了&#xff0c;心自然就野了&#xff01;身边的各种朋友自然就多了起来&#xff01; 有一天晚上&#xff0c;一个年轻漂亮的女同事生日&#xff0c;Jack 受邀…

python 自定义包的实现

1. 代码目录 创建自定义包的时候&#xff0c;原理是当 python 检测到一个目录下存在 __init__.py 文件时&#xff0c;python 就会把它当成一个模块(module)。 下面这个例子是网上整理的代码&#xff0c;但是有些小改动&#xff0c;可以直接拿来就用。 看代码结构&#xff1a;…

springboot+vue+mybatis社交网络平台+PPT+论文+讲解+售后

近些年来&#xff0c;随着科技的飞速发展&#xff0c;互联网的普及逐渐延伸到各行各业中&#xff0c;给人们生活带来了十分的便利&#xff0c;社交网络平台利用计算机网络实现信息化管理&#xff0c;使整个社交网络管理的发展和服务水平有显著提升。 本文拟采用Eclipse开发工具…

免费证件照一键换底色

最近星期天在家搞了一个小工具&#xff0c;在这里分享下! 废话不多说看看效果&#xff1a; 效果还不错&#xff0c;需要的可以联系我!!!!!!!!! 别的网上可都是一次五块钱这种。太贵了。。&#xff01;&#xff01;

Python - 深度学习系列33 - ollama_langchain_ppt生成

说明 只是为了速记一下这个实践过程。整体上说&#xff0c;这个结果并不是那么好用&#xff0c;但有一些可以借鉴的地方。 先看结果&#xff1a; 生成的PPT 说的直白点&#xff0c;就是用大模型生成了一堆没太有意义的文字&#xff0c;然后做成ppt。所以实用是不成的&#…

Golang | Leetcode Golang题解之第85题最大矩形

题目&#xff1a; 题解&#xff1a; func maximalRectangle(matrix [][]byte) (ans int) {if len(matrix) 0 {return}m, n : len(matrix), len(matrix[0])left : make([][]int, m)for i, row : range matrix {left[i] make([]int, n)for j, v : range row {if v 0 {continu…