Linux基础内容(20)—— 共享内存

news/2024/4/24 19:56:00/

Linux基础内容(19)—— 进程间通信(介绍与管道内容)_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/130034918?spm=1001.2014.3001.5502

目录

1.共享内存的原理

2.共享内存的概念和特点

创建共享内存 

共享内存的形式

共享内存(ipc资源)的调用和特征

用户接口删除共享内存

共享内存关联

去关联

特点

共享内存大小


1.共享内存的原理

1.由于进程本身的结构 --- 虚拟内存地址空间,使得进程间互相看不见对面的物理内存地址,达不到进程间直接通信的目的

2.但如果OS能提供一个接口,这个接口是用户调用之可以构建出共享的内存,并且共享内存的地址通过页表映射到虚拟地址空间中,两个进程如果都这里映射了同一个共享内存,那么就可以达到进程间通信的目的

 3.如果不想通信了,需要切断两边的映射(去关联)和释放共享内存

理解:

1.进程间通信是专门设计的,用户只需要调用接口

2.共享内存是一种通信方式,所有想通信的进程都可以用

3.OS中一定可能同时存在多个共享内存

2.共享内存的概念和特点

通过让不同的进程看到同一块内存块,这样的内存称之为共享内存

创建共享内存 

size:申请多大的共享内存

key:能进行唯一性表示的数,具体内容不重要,看到同一个key就可以看到同一个资源了

shmflg:

IPC_CREAT -- 指定的共享内存,不存在,创建;存在,共享内存标志返回

IPC_EXCL -- 无法单独使用;只有当 IPC_CREAT|IPC_EXCL 同时使用,如果不存在,创建,如果存在,出错返回

返回值:成功返回共享内存的标识符,失败返回-1

注意:创建时还得把共享内存的权限属性给传入

转换得到key值

pathname:一个字符串

proj_id:一个数字

这样组合出唯一的数字key返回

返回:成功返回key值,失败-1

共享内存的形式

1.c语言中malloc函数需要输入大小,但是free反而不需要。这是因为malloc函数不会只给我们申请指定大小空间,它一定要申请更大的空间来存储它的属性方便管理

2.关于以前进程的也是先描述再组织

3.那么对于共享内存,也是如此,我们不会只申请指定大小就结束了,我们还会存储共享内存的相关属性,这样方便管理,那么对于共享内存而言:物理内存存储块+共享内存属性

4.上面说过,共享内存可能有很多,那么如何表示唯一性呢?答案很明显,key就是唯一的,那么创建时我们能通过key得到唯一的共享内存。

5.那么key也是一种属性,所以这个key也被放在描述共享内存的属性之中。

6.那么链接共享内存就是通过得到一样的key,在组织数据结构中遍历找每个内存属性中放key的值,找到了就唯一指定了,key是内核级别的属性

7.shmid和key的关系是:shmid是在用户级别调用的数值。其区别就于fd和inode类似,inode内核级别表示文件的唯一性,而用户直接不使用inode,而是调用函数返回的fd进行操作

共享内存(ipc资源)的调用和特征

1.共享内存的生命周期随着OS的,不随进程而消除(system V特性)

 2.ipcs -m查看共享内存

perm:文件权限

nattch:关联的进程

3.ipcrm -m shmid删除共享内存

3.ipcs -q查看消息队列

4. ipcs -s查看信号量

用户接口删除共享内存

该接口是对共享内存进行控制,控制里包括删除

shmid:指定shmid

cmd:指令

IPC_STAT

IPC_SET

IPC_RMID:立即移除共享内存

buf:获取属性存储空间,不要则输入nullptr

返回值:失败则-1

删除该共享内存的前提就是将内存与进程相关联,毕竟调用系统接口删除的前提是有这块地址

共享内存关联

用于映射到虚拟地址空间的哪个位置中

后两位数指定位置,一般不指定:设为nullptr和0

返回值:共享内存地址空间的返回值

失败是返回-1

去关联

shmdt()

 返回0成功,-1失败

特点

优点:所以进程间通信中速度最快的

因为我们写入共享内存,另一方就能得到,能大大减少拷贝的次数

同样的代码用来通信,(单纯的收发消息)需要拷贝几次才能完成任务:

管道实现:4+2次

共享内存实现:2+2次

缺点:不给我们进行同步互斥消息的,没有对数据做任何保护

共享内存大小

建议是4KB的整数倍

因为系统分配共享内存是以4KN为单位的 -- 内存划分内存块的基本单位

给大给小都会向上取整:使用的内存显示为申请的,但是内存中的确开辟,只是用户调不到

comm.hpp
#ifndef _COMM_HPP_
#define _COMM_HPP_#include <iostream>
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>#define PATHNAME "."
#define PROJ_ID 0x66
#define MAX_SIZE 4096key_t getKey()
{key_t k = ftok(PATHNAME, PROJ_ID);if (k < 0){std::cerr << errno << ":" << strerror(errno) << std::endl;exit(1);}return k;
}int getShmHelper(key_t k, int flags)
{int shmid = shmget(k, MAX_SIZE, flags);if(shmid<0){std::cerr << errno << ":" << strerror(errno) << std::endl;exit(2);}return shmid;
}int creatShm(key_t k)
{return getShmHelper(k, IPC_CREAT | IPC_EXCL | 0600); // 创建一个新的,所以如果没有就判错
}int getShm(key_t k)
{return getShmHelper(k, IPC_CREAT /*0*/); // 调用创建的,0也可以
}void* attchShm(int shmid)
{void* mem = shmat(shmid,nullptr,0);if((long long)mem==-1L){std::cerr << errno << ":" << strerror(errno) << std::endl;exit(3);}return mem;
}void detachShm(void* start)
{if(shmdt(start)==-1){std::cerr << errno << ":" << strerror(errno) << std::endl;}
}void deleteShm(int shmid)
{if(shmctl(shmid,IPC_RMID,nullptr)==-1){std::cerr << errno << ":" << strerror(errno) << std::endl;exit(1);}
}#endifserver.cc
#include "comm.hpp"int main()
{key_t k = getKey();printf("0x%x\n",k);int shmid = creatShm(k);printf("shmid:%d\n",shmid);sleep(5);char* start = (char*)attchShm(shmid);printf("attach success, adress start: %p\n",start);//使用while(true){shmid_ds ds;shmctl(shmid,IPC_STAT,&ds);printf("获取信息: size:%d ,pid: %d ,myself: %d",ds.shm_segsz,ds.shm_cpid,getpid());printf("client say:%s\n",start);sleep(1);}//去关联detachShm(start);//删除deleteShm(shmid);return 0;
}client
#include "comm.hpp"int main()
{key_t k = getKey();printf("0x%x\n",k);int shmid = getShm(k);printf("shmid:%d\n",shmid);sleep(5);char* start = (char*)attchShm(shmid);const char* message = "hello server,我是另一个进程";pid_t id = getpid();int cnt = 1;//char* buffer[1024];while(true){snprintf(start,MAX_SIZE,"%s[pid:%d][消息编号%d]",message,id,cnt);//snprintf(buffer,sizeof(buffer),"%s[pid:%d][消息编号%d]",message,id,cnt);//memcpy(start,buffer,strlen(buffer)+1);// pid,count,mess}detachShm(start);return 0;
}

http://www.ppmy.cn/news/48346.html

相关文章

第七章节 spring AOP

《Spring》篇章整体栏目 ————————————————————————————— 【第一章】spring 概念与体系结构 【第二章】spring IoC 的工作原理 【第三章】spring IOC与Bean环境搭建与应用 【第四章】spring bean定义 【第五章】Spring 集合注入、作用域 【第六章】…

什么是计算量flops,什么是参数量params?

flops与params 计算量对应我们之前的时间复杂度&#xff0c;参数量对应于我们之前的空间复杂度&#xff0c;这么说就很明显了 也就是计算量要看网络执行时间的长短&#xff0c;参数量要看占用显存的量 其中最重要的衡量CNN 模型所需的计算力就是flops&#xff1a; FLOPS&…

显存不够用?一种大模型加载时节约一半显存的方法

Loading huge PyTorch models with linear memory consumption 本文主要介绍了一种用于加载巨大模型权重时节约接近一半显存的方法 首先&#xff0c;创建一个模型: import torch from torch import nnclass BoringModel(nn.Sequential):def __init__(self):super().__init__…

【Leetcode -剑指Offer 22.链表中倒数第k个结点 -203.移除链表元素】

Leetcode Leetcode -剑指Offer 22.链表中倒数第k个结点Leetcode -203.移除链表元素 Leetcode -剑指Offer 22.链表中倒数第k个结点 题目&#xff1a;输入一个链表&#xff0c;输出该链表中倒数第k个节点。为了符合大多数人的习惯&#xff0c;本题从1开始计数&#xff0c;即链表…

OSCP-Clyde(rabbitmq中间件、erlang服务4369、修改Payload、nmap提权)

目录 扫描 FTP erlang服务(4369) 提权 扫描 21/tcp open ftp vsftpd 3.0.3 | ftp-anon: Anonymous FTP login allowed (FTP code 230) | drwxr-xr-x 2 ftp ftp 4096 Apr 24 2020 PackageKit | drwxr-xr-x 5 ftp ftp 4096 Apr 24 2020 apache2 | drwxr-xr-x 5 ftp ftp 409…

云原生之在kubernetes集群下部署Mysql应用

云原生之在kubernetes集群下部署mysql应用 一、Mysql介绍二、kubernetes集群介绍1.k8s简介2.k8s架构图 三、本次实践介绍1.本次实践简介2.本次环境规划 三、检查本地k8s集群环境1.检查k8s各节点状态2.检查k8s版本3.检查k8s系统pod状态 四、编辑mysql.yaml文件五、创建mysql应用…

Redis分布式锁有哪些缺点?如何解决?

目录 一、死锁问题&#xff1a; 二、锁竞争问题&#xff1a; 三、时效性问题&#xff1a; 四、单点故障问题&#xff1a; 五、高并发量下锁抢占时间长的问题 一、死锁问题&#xff1a; 因为每个客户端在设置锁过期时间时可能出现网络延迟等原因&#xff0c;有可能出现某个…

五项热门技术领域和应用场景

介绍五种当下比较热门的技术&#xff0c;分别是人工智能、云计算、数据分析、微服务和区块链。每种技术都有自己的定义、子领域、应用场景和学习难度。这些技术都有着广阔的发展前景和市场需求&#xff0c;对于想要从事或了解这些领域的人来说&#xff0c;都是很有价值的知识。…

centos7安装nginx的三种方式~yum源,源码,Docker

目录 1.yum安装&#xff1a;Centos7源默认没有nginx 2.源码安装&#xff1a; 3.Docker安装&#xff1a; 1.yum安装&#xff1a;Centos7源默认没有nginx 配置yum源&#xff1a; wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo 查看nginx源&…

Vue中的路由导航

声明式路由导航 router官网-起步 声明式路由导航其实就是使用官方给的<router-link>路由导航标签直接进行路由跳转 <body> <div id"app"><!--<router-link>路由导航标签&#xff0c;用于找到path属性中url对应的组件&#xff0c;通过传入…

Spring的循环依赖

什么是循环依赖&#xff1f; 循环依赖其实就是循环引用&#xff0c;也就是两个或者两个以上的 bean 互相持有对方&#xff0c;最终形成闭环。比如 A 依赖于 B&#xff0c;B 依赖于 C&#xff0c;C 又依赖于 A。如下图&#xff1a; 注意&#xff0c;这里不是函数的循环调用&…

rk3568-rk809电池电量计

简介&#xff1a; RK809 集成在RK3568上的一个高性能的 PMIC&#xff08;(Power Management IC):电源管理集成电路&#xff09;&#xff0c;PMIC全称Power management integrated circuit&#xff0c;一般情况下是一颗独立于主控的芯片&#xff0c;集成了电源控制&#xff0c;电…

Nginx rewrite ——重写跳转

Nginx常见模块 http http块是Nginx服务器配置中的重要部分&#xff0c;代理、缓存和日志定义等绝大多数的功能和第三方模块的配置都可以放在这模块中。作用包括&#xff1a;文件引入、MIME-Type定义、日志自定义、是否使用sendfile传输文件、连接超时时间、单连接请求数上限等…

不讲废话普通人了解 ChatGPT——基础篇第一课

wx供重浩&#xff1a;创享日记 获取更多内容 文章目录 前言什么是 ChatGPT它是如何工作的ChatGPT 和其它机器人有什么不同 前言 不知道大家在第一次会使用 ChatGPT 并尝试和他对话时有没有感到震惊。当ChatGPT首次推出时&#xff0c;我立即被它的功能所吸引。 曾经在遇到繁杂…

设计模式 -- 装饰模式

前言 月是一轮明镜,晶莹剔透,代表着一张白纸(啥也不懂) 央是一片海洋,海乃百川,代表着一块海绵(吸纳万物) 泽是一柄利剑,千锤百炼,代表着千百锤炼(输入输出) 月央泽,学习的一种过程,从白纸->吸收各种知识->不断输入输出变成自己的内容 希望大家一起坚持这个过程,也同…

【通知】CSDN学院:<华为流程体系课程> 正式上线啦!

目录 前言 适用人群 你将收获 课程介绍 前言 经过两个月的准备和短视频测试&#xff0c;这门介绍华为流程体系的课程就正式上线了。 虽然由于公开的原因&#xff0c;华为的发展受到了一定程度的影响&#xff0c;但是丝毫不妨碍企业、以及一些个人对学习华为的热情。 原因…

Qt扫盲-QAbstractSeries理论总结

QAbstractSeries理论总结 一、概述二、常用函数1. 属性2. 设置功能3. 显示隐藏4. 与 绘图的交互 三、信号 一、概述 QAbstractSeries类是所有Qt图表线的基类。通常&#xff0c;特定于序列类型的继承类会被使用&#xff0c;而不是这个基类。这个基类只是提供了一些管理和控制这…

使用Swagger生成在线文档

目录 1&#xff1a;Swagger介绍 2&#xff1a;使用 2.1&#xff1a;swaager集成boot依赖 2.2&#xff1a;配置文件中配置相关信息 2.3&#xff1a;在启动类中加入相关注解 2.4&#xff1a;测试 3&#xff1a;swagger常用注解 1&#xff1a;Swagger介绍 在前后端分离开发…

【华为OD机试 2023最新 】最大利润(C语言题解 )

文章目录 题目描述输入描述输出描述用例题目解析C语言题目描述 商人经营一家店铺,有number种商品, 由于仓库限制每件商品的最大持有数量是item[index] 每种商品的价格是item-price[item_index][day] 通过对商品的买进和卖出获取利润 请给出商人在days天内能获取的最大的利润…

系统可用性——冗余就够了吗?

导言 为了提高系统的可用性&#xff0c;如今很多集成商都号称采用了冗余设备来满足客户需求&#xff0c;乍一看产品性能提高不少。当我们再回顾其产品时&#xff0c;不禁要思考两个问题&#xff1a; 系统真的做到冗余了吗&#xff1f;仅仅使用冗余就够了吗&#xff1f; 回答…