【Linux】:共享内存

共享内存

  • 一.原理
  • 二.创建共享内存
    • 1.shmget
    • 2.写一个共享内存代码
  • 三.进行通信
    • 1.各种接口
    • 2.各接口使用代码
    • 3.一次简单的通信
    • 四.共享内存的特点

一.原理

直接原理

共享内存顾名思义就是共同使用的一块空间。

在这里插入图片描述

很明显操作系统需要对这块内存进行管理,那么就避免不了先描述后组织的策略。

二.创建共享内存

1.shmget

申请一块共享内存-shmget

在这里插入图片描述

第二个参数:创建共享内存的大小,单位字节。

第三个参数:多个选项
在这里插入图片描述

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

操作系统怎么保证不同进程看到同一个共享内存呢?怎么知道这块内存是否存在呢? 这就需要对第一个参数进行讨论了。

在这里插入图片描述

2.写一个共享内存代码

comm.hpp

#ifndef __COMM_HPP__
#define __COMM_HPP__
#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>using namespace std;const int size=4096;
const string path="/home/chz";//任意写
const int proj_id=0x6666;//任意写key_t Getkey()//获取一个key
{key_t k=ftok(path.c_str(),proj_id);if(k<0){perror("Create key wrong\n");exit(1);}cout<<"Create key sucess,key:"<<k<<endl;return k;
}int GetshareMem()//获取一个chmid
{key_t k=Getkey();int shmid=shmget(k,size,IPC_CREAT|IPC_EXCL|0666);//创建方式和权限if(shmid<0){perror("Create shmget wrong\n");exit(2);}cout<<"Create shmget sucess,shmid;"<<shmid<<endl;return shmid;
}#endif

前面说过共享内存如果不主动释放会一直存在,所以在调用该函数后我们可以使用ipcs -m查看内核的进程资源。

在这里插入图片描述

perms是权限,nattch是与之相连的文件,byte是共享内存大小(建议一般按4096的整数倍创建,因为系统一次分配的最小内存是4KB)。

使用ipcrm -m+shmid可以手动删除。

在这里插入图片描述

三.进行通信

1.各种接口

将共享内存挂入

在这里插入图片描述

第一个参数毫无疑问是共享内存标识符。

第二个参数一般设置为NULL。因为共享内存是在物理内存上,要将其挂到虚拟内存的共享区,但具体挂到共享区哪个位置一般由操作系统决定。该函数的返回值就是具体的起始地址。

第三个参数一般设为0。它是改变挂接时的权限,虽然我们设置的共享内存权限是666,但可以通过这个参数让它只读。

取消挂入

在这里插入图片描述

控制共享内存

在这里插入图片描述

第二个参数:要进行什么操作。(有许多参数可以自行查看,这里使用 IPC_RMID删除该共享内存)

第三个参数:共享内存的属性。

2.各接口使用代码

processa.cc

#include"comm.hpp"
#include <unistd.h>int main()
{int shmid=GetshareMem();sleep(3);char*shmaddr=(char*)shmat(shmid,NULL,0);//将共享内存挂入cout<<"挂入内存"<<endl;sleep(3);shdit(shmaddr);//取消挂入cout<<"取消挂入"<<endl;sleep(3);shmctl(shmid,IPC_RMID,nullptr);//销毁共享内存cout<<"销毁共享内存"<<endl;return 0;
}

在这里插入图片描述

3.一次简单的通信

稍微修改一下comm.hpp,主要在shmget,当一个进程创建时,让另一个进程能获取

#ifndef __COMM_HPP__
#define __COMM_HPP__
#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>using namespace std;const int size=4096;
const string path="/home/chz";//任意写
const int proj_id=0x6666;//任意写key_t Getkey()//获取一个key
{key_t k=ftok(path.c_str(),proj_id);if(k<0){perror("Create key wrong\n");exit(1);}cout<<"Create key sucess,key:"<<k<<endl;return k;
}int GetShareMemHelper(int flag)//获取一个chmid
{key_t k=Getkey();int shmid=shmget(k,size,flag);//创建方式和权限if(shmid<0){perror("Create shmget wrong\n");exit(2);}cout<<"Create shmget sucess,shmid;"<<shmid<<endl;return shmid;
}int CreateShm()
{return GetShareMemHelper(IPC_CREAT|IPC_EXCL|0666);
}int GetShm()
{return GetShareMemHelper(IPC_CREAT);
}#endif

processa.cc

#include"comm.hpp"
#include <unistd.h>int main()
{int shmid=CreateShm();//创建共享内存//挂入内存//获取起始地址,并把它当作字符串使用char*shmaddr=(char*)shmat(shmid,nullptr,0);while(true){//直接读取cout<<"I am read:";cout<<shmaddr<<endl;sleep(1);}shmdt(shmaddr);//取消挂起shmctl(shmid,IPC_RMID,nullptr);return 0;
}

processb.cc

#include"comm.hpp"int main()
{int shmid=GetShm();//获取共享内存//挂入内存//获取起始地址,并把它当作字符串使用char*shmaddr=(char*)shmat(shmid,nullptr,0);while(true){cout<<"please Enter:";fgets(shmaddr,4096,stdin);//直接从键盘读入}return 0;
}

makefile

.PHONY:all
all:processa processbprocessa:processa.ccg++ -o $@ $^ -std=c++11
processb:processb.ccg++ -o $@ $^ -std=c++11.PHONY:clean
clean:rm -f processa processb

在这里插入图片描述

四.共享内存的特点

1.共享内存没有同步互斥之类的保护机制。(即使没有写入也依然会读)
2.共享内存是所有的进程通信中最快的。(拷贝少)
3.共享内存里的所有数据由用户自己维护。(操作系统不会自动将数据清零)

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

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

相关文章

动态规划45(Leetcode790多米诺和拖米诺平铺)

代码&#xff1a; &#xff01;&#xff01;动态规划基础版完结撒花&#x1f389; class Solution {public int numTilings(int n) {long MOD 1000000007;int[] dp new int[n1];dp[0]1;for(int i1;i<n;i){dp[i]dp[i-1]%MOD;dp[i]%MOD;if(i>2){dp[i]dp[i-2]%MOD;dp[i]…

mysql命令行(mysql-client)连接数据库

有时项目连接不上数据库&#xff0c;报错鉴权失败&#xff0c;先用mysql工具连接下&#xff0c;容易发现问题。 直接输入mysql看是否已安装&#xff0c;如果没有就安装下。 yum -y install mysql-client; 这个名称一直记不准&#xff0c;有时记为mysql-cli&#xff0c;结果发现…

Python pip 镜像源设置指南

文章目录 Python pip 镜像源设置指南前言安装单个包使用PyPI镜像使用镜像升级 pip设为默认pip镜像结语 Python pip 镜像源设置指南 前言 平时在使用 pip 安装一些包的时候速度非常慢,本文介绍如何在 Python3 下设置 PyPI 设置镜像源,本文以给 Python3 设置清华 镜像源举例. …

2023.11.20使用flask做一个简单图片浏览器

2023.11.20使用flask做一个简单图片浏览器 功能&#xff1a; &#xff08;1&#xff09;输入指定路径&#xff0c;打开文件夹 &#xff08;2&#xff09;判断文件格式为图片 &#xff08;3&#xff09;在前端进行预览 &#xff08;4&#xff09;使用bootstrap进行简单美化 ma…

win11,引导项管理

1&#xff0c;打开cmd,输入msconfig 2,进入引导选项卡 3&#xff0c;删除不需要的引导项

【CSH 入门基础 9 -- 输出 csh 脚本中每一句命令】

文章目录 输出csh脚本中每一句命令 输出csh脚本中每一句命令 在 csh 或 tcsh 脚本中&#xff0c;如果你想要输出脚本中的每一句执行&#xff0c;你可以在脚本的开头使用 -v&#xff08;verbose&#xff09;选项。这个选项会使得 shell 在执行命令前先打印出来。 要在脚本中使…

蓝桥杯每日一题2023.11.21

题目描述 “蓝桥杯”练习系统 (lanqiao.cn) 题目分析 思路&#xff1a; 1.去重排序将其进行预处理 2.用gcd得到最简比值 3.用gcd_sub分别计算分子、分母的指数最大公约数 #include<bits/stdc.h> using namespace std; const int N 110; typedef long long ll; ll…

前端性能优化之LightHouse

优质博文&#xff1a;IT-BLOG-CN 一、LightHouse环境搭建 LightHouse是一款由Google开发的开源工具&#xff0c;用于评估Web应用程序的性能和质量。可以将其看作是一个Chrome扩展程序运行&#xff0c;或从命令行运行。为LightHouse提供一个需要审查的网址&#xff0c;它将针对…

展开语法、剩余语法

展开语法定义 展开语法Spread Syntax&#xff0c;可以在函数调用/数组构造时&#xff0c;将数组表达式或者string在语法层面展开&#xff1b;还可以在构造字面量对象时&#xff0c;将对象表达式按照key-value的方式展开。&#xff08;字面量一般指[1, 2, 3]或者{name:"md…

V100 GPU服务器安装CUDNN教程

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

【如何学习Python自动化测试】—— 鼠标键盘操作

5 、 鼠标键盘操作 在浏览器中&#xff0c;通常会用到鼠标来进行操作&#xff0c;比如右键菜单中选择一个操作&#xff0c;在 selenium 中提供了下列鼠标相关操作。 ActionChains 类提供了以下方法&#xff1a; 点击鼠标&#xff1a;click()右击鼠标&#xff1a;context…

Pandas数据清洗_Python数据分析与可视化

Pandas数据清洗 删除缺失值检测缺失值填充缺失值拉格朗日插值线性插值 在处理数据的时候&#xff0c;需要对数据进行一个清洗过程。清洗操作包括&#xff1a;空白行的删除、数据完整性检验、数据填充、插值等内容。 下面是数据清洗过程中使用的具体方法 删除缺失值 DataFram…

Go语言常用命令详解(三)

文章目录 前言常用命令go get示例参数说明 go install示例参数说明 go list示例 go mod示例参数说明 go work基本用法示例 go tool示例 go version示例 go vet示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命…

智能座舱架构与芯片- (14) 测试篇 上

一、 验证平台概要 1.1 测试软件方法论 “软件定义汽车” 的时代&#xff0c;软件在整车制造中的重要性日渐凸显。但不同于其他行业的软件开发&#xff0c;汽车行业有自己独特的软件开发要求。首先是需求严谨、需求层次复杂、需要通过专业的工具进行管理&#xff1b;其次开发…

数据中台之用户画像

用户画像应用领域较为广泛,适合于各个产品周期,从新用户的引流到潜在用户的挖掘、 从老用户 的培养到流失用户的回流等。通过挖掘用户兴趣、偏好、人口统计特征,可以 直接 作用于提升营销精准 度、推荐匹配度,最终提升产品服务和企业利润。还包括广告投放、产品布局和行业报…

从0开始学习JavaScript--深入理解JavaScript的async/await

JavaScript的异步编程在过去经历了回调地狱、Promise的引入&#xff0c;而今&#xff0c;通过async/await&#xff0c;让我们获得了更加优雅、可读性更高的异步编程方式。本文将深入探讨async/await的概念、用法&#xff0c;并通过丰富的示例代码展示其在实际应用中的威力。 理…

JVM垃圾收集器

什么是垃圾收集器 Java虚拟机的垃圾收集器是内存回收的具体实现&#xff0c;主要用于回收不再使用的对象&#xff0c;释放内存空间。Java虚拟机提供了多种垃圾收集器&#xff0c;不同的垃圾收集器适用于不同的场景和需求。 在C中&#xff0c;对象所占的内存在程序结束运行之前…

Windows to Go U盘系统制作(未测完成)

三、Windows U盘系统制作 1、下载windows镜像&#xff0c;并通过Windows To Go方式制作&#xff0c;具体选项参考下面截图 2、选择Windows版本 3、配置Windows 体验相关参数

C++ Qt TCP协议,处理粘包、拆包问题,加上数据头来处理

目录 前言&#xff1a; 场景&#xff1a; 原因&#xff1a; 解决&#xff1a; 方案2具体细节&#xff1a; 纯C服务端处理如下&#xff1a; Qt客户端处理如下&#xff1a; 前言&#xff1a; tcp协议里面&#xff0c;除了心跳检测是关于长连接操作的处理&#xff0c;这个在…

STM32通用定时器产生PWM信号

STM32通用定时器产生PWM信号 PWM信号stm32定时器PWM生成模式PWM配置基本步骤PWM周期计算CubeMX配置代码展现 本期内容我将展示使用STM32通用定时器产生PWM信号&#xff0c;这里以定时器3通道3为例 PWM信号 如果还不懂的话&#xff0c;可以看看 &#xff1a; “蓝桥杯单片机学习…