【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.rhkb.cn/news/200679.html

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

相关文章

Servlet执行流程Servlet 生命周期

Servlet 生命周期 对象的生命周期指一个对象从被创建到被销毁的整个过程 import javax.servlet.*; import javax.servlet.annotation.WebServlet; import java.io.IOException; WebServlet(urlPatterns "/demo",loadOnStartup 10) public class ServletDemo imple…

华为ac+fit漫游配置案例

Ap漫游配置: 其它配置上面一样,ap管理dhcp和业务dhcp全在汇聚交换机 R1: interface GigabitEthernet0/0/0 ip address 11.1.1.1 255.255.255.0 ip route-static 12.2.2.0 255.255.255.0 11.1.1.2 ip route-static 192.168.0.0 255.255.0.0 11.1.1.2 lsw1: vlan batch 100 200…

存储日志数据并满足安全要求

日志数据是包含有关网络中发生的事件的记录的重要信息&#xff0c;日志数据对于监控网络和了解网络活动、用户操作及其动机至关重要。 由于网络中的每个设备都会生成日志&#xff0c;因此收集的数据量巨大&#xff0c;管理和存储所有这些数据成为一项挑战&#xff0c;日志归档…

Windows系统如何安装与使用TortoiseSVN客户端,并实现在公网访问本地SVN服务器

文章目录 前言1. TortoiseSVN 客户端下载安装2. 创建检出文件夹3. 创建与提交文件4. 公网访问测试 前言 TortoiseSVN是一个开源的版本控制系统&#xff0c;它与Apache Subversion&#xff08;SVN&#xff09;集成在一起&#xff0c;提供了一个用户友好的界面&#xff0c;方便用…

2023年以就业为目的学习Java还有必要吗?

文章目录 1活力四射的 Java2从零开始学会 Java3talk is cheap, show me the code4结语写作末尾 现在学 Java 找工作还有优势吗&#xff1f; 在某乎上可以看到大家对此问题的热议&#xff1a;“2023年以就业为目的学习Java还有必要吗&#xff1f;” 。有人说市场饱和&#xff0c…

关于lenra你需要了解的

monorepo&#xff1a;项目代码管理方式&#xff0c;单个仓库中管理多个项目是一种设计思想 lenra&#xff1a;是一种工具&#xff0c;对于使用npm和git管理多软件包代码仓库的工作流程进行优化 使用这些工具的优点&#xff1a; 公共依赖只要安装一次&#xff0c;Monorepo 中…

C/C++内存管理(1):C/C++内存分布,C++内存管理方式

一、C/C内存分布 1.1 1.2 二、C内存管理方式 C可以通过操作符new和delete进行动态内存管理。 2.1 new和delete操作内置类型 int main() {int* p1 new int;// 注意区分p2和p3int* p2 new int(10);// 对*p2进行初始化 10int* p3 new int[10];// p3 指向一块40个字节的int类…

网络运维与网络安全 学习笔记2023.11.21

网络运维与网络安全 学习笔记 第二十二天 今日目标 端口隔离原理与配置、路由原理和配置、配置多路由器静态路由 配置默认路由、VLAN间通信之路由器 端口隔离原理与配置 端口隔离概述 实现报文之间的2层隔离&#xff0c;除了使用VLAN技术以后&#xff0c;还可以使用端口隔…

Linux socket编程(5):三次握手和四次挥手分析和SIGPIPE信号的处理

在我之前写的Wireshark抓包&#xff1a;理解TCP三次握手和四次挥手过程中&#xff0c;通过抓包分析了TCP传输的三次握手和四次挥手的过程。在这一节中&#xff0c;将分析在Linux中的三次握手和四次挥手的状态和过程&#xff0c;另外还有一个在我们编程过程中值得注意的SIGPIPE信…

gitBash中如何使用Linux中的tree命令

文章目录 在gitBash中安装tree的目的如何安装安装完成,就可以直接完美适配Linux系统了在gitBash中安装tree的目的 如下图,powershell虽然可以看做是window下的Linux系统,但是根本就不适配很多Linux中的命令 如何安装 tree.exe安装网址 下载 tree 命令的 二进制包,安装 tr…

OAK相机通过振动测试!

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是助手君。 当…

【python】Python生成GIF动图,多张图片转动态图,pillow

pip install pillow 示例代码&#xff1a; from PIL import Image, ImageSequence# 图片文件名列表 image_files [car.png, detected_map.png, base64_image_out.png]# 打开图片 images [Image.open(filename) for filename in image_files]# 设置输出 GIF 文件名 output_g…

java算法学习索引之数组矩阵问题

一 将正方形矩阵顺时针转动90 给定一个NN的矩阵matrix&#xff0c;把这个矩阵调整成顺时针转动90后的形式。 顺时针转动90后为&#xff1a; 【要求】额外空间复杂度为O&#xff08;1&#xff09;。 public void rotate(int[][] matrix) {int tR 0; // 左上角行坐标int tC 0;…

香港科技大学广州|机器人与自主系统学域博士招生宣讲会—同济大学专场!!!(暨全额奖学金政策)

在机器人和自主系统领域实现全球卓越—机器人与自主系统学域 硬核科研实验室&#xff0c;浓厚创新产学研氛围&#xff01; 教授亲临现场&#xff0c;面对面答疑解惑助攻申请&#xff01; 一经录取&#xff0c;享全额奖学金1.5万/月&#xff01; &#x1f559;时间&#xff1a;…

STM32 Flash

FLASH简介 Flash是常用的用于存储数据的半导体器件&#xff0c;它具有容量大&#xff0c;可重复擦写&#xff0c;按“扇区/块”擦除、掉电后数据可继续保存的特性。 常见的FLASH主要有NOR FLASH和NAND FLASH两种类型。NOR和NAND是两种数字门电路&#xff0c;可以简单地认为FL…

多线程的概念

点击链接返回标题-> 什么是进程&#xff1f; 进程&#xff08;Process&#xff09;&#xff0c;是程序的基本执行实体。 在早期面向进程设计的计算机结构中&#xff0c;进程是程序的基本执行实体&#xff1b; 在当代面向线程设计的计算机结构中&#xff0c;进程是线程的容器…

【阿里云】图像识别 摄像模块 语音模块

USB 摄像头模块测试及配置 一、首先将 USB 摄像头插入到 Orange Pi 开发板的 USB 接口中二、然后通过 lsmod 命令可以看到内核自动加载了下面的模块三、通过 v4l2-ctl 命令可以看到 USB 摄像头的设备节点信息为 /dev/video0四、使用 fswebcam 测试 USB 摄像头五、使用 motion …

opencv-简单图像处理

图像像素存储形式  对于只有黑白颜色的灰度图&#xff0c;为单通道&#xff0c;一个像素块对应矩阵中一个数字&#xff0c;数值为0到255, 其中0表示最暗&#xff08;黑色&#xff09; &#xff0c;255表示最亮&#xff08;白色&#xff09; 对于采用RGB模式的彩色图片&#…

人工智能基础_机器学习046_OVR模型多分类器的使用_逻辑回归OVR建模与概率预测---人工智能工作笔记0086

首先我们来看一下什么是OVR分类.我们知道sigmoid函数可以用来进行二分类,那么多分类怎么实现呢?其中一个方法就是使用OVR进行把多分类转换成二分类进行计算. OVR,全称One-vs-Rest,是一种将多分类问题转化为多个二分类子问题的策略。在这种策略中,多分类问题被分解为若干个二…

Startdrive中上传参数设置的具体方法和注意事项

Startdrive中上传参数设置的具体方法和注意事项 适用于配 SINAMICS S120、G130、G150、S150和MV(基于CU3x0-2的驱动器)和所有启动驱动器版本INAMICS G115D/G120/G120D/G120C/G120P/G110M(基于CU2x0-2的驱动器) 根据SINAMICS类型的不同,Startdrive中的Upload参数有所不同。…