【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 processb

processa:processa.cc
	g++ -o $@ $^ -std=c++11
processb:processb.cc
	g++ -o $@ $^ -std=c++11

.PHONY:clean
clean:
	rm -f processa processb

在这里插入图片描述

四.共享内存的特点

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MCU 的 TOP 15 图形GUI库:选择最适合你的图形用户界面(一)

在嵌入式系统开发中&#xff0c;选择一个合适的图形用户界面&#xff08;GUI&#xff09;库是至关重要的。在屏幕上显示的时候&#xff0c;使用现成的图形库&#xff0c;这样开发人员就不需要弄清楚底层任务&#xff0c;例如如何绘制像素、线条、形状&#xff0c;如果再高级一点…

一种全新且灵活的 Prompt 对齐优化技术

并非所有人都熟知如何与 LLM 进行高效交流。 一种方案是&#xff0c;人向模型对齐。 于是有了 「Prompt工程师」这一岗位&#xff0c;专门撰写适配 LLM 的 Prompt&#xff0c;从而让模型能够更好地生成内容。 而另一种更为有效的方案则是&#xff0c;让模型向人对齐。 这也是…

ES 查询语法-详解

文章目录 1.DSL查询文档1.1.DSL查询分类1.2.全文检索查询1.2.1.使用场景1.2.2.基本语法1.2.3.总结 1.3.精准查询1.3.1.term查询1.3.2.总结 1.DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsearch提供了基于JSON的DSL&#xff…

信号的处理时机(内核态,用户态,如何/为什么相互转换,内核空间,cpu寄存器),信号的处理流程详细介绍+抽象图解

目录 信号的处理时机 引入 思考 -- 什么时候才能算合适的时候呢? 用户态转为内核态 引入 内核地址空间 引入 思考 -- 进程为什么能切换成内核态呢? 虚拟地址空间 注意点 原理 (总结一下) 为什么如何进入内核态 引入 介绍 底层原理(int 80) cpu的寄存器 用…

LOIS: Looking Out of Instance Semanticsfor Visual Question Answering

目录 一、论文速读 1.1 摘要 1. 2 论文概要总结 二、论文精度 2.1 论文试图解决什么问题&#xff1f; 2.2 论文中提到的解决方案之关键是什么&#xff1f; 2.3 用于定量评估的数据集是什么&#xff1f;代码有没有开源&#xff1f; 2.4 这篇论文到底有什么贡献&#xff…

智能座舱架构与芯片- (15) 测试篇 下

三、持续集成与交付 3.1 自动化编译框架 在智能座舱软件中&#xff0c;分为上层应用软件和底层软件。有些上层应用软件是与指令集平台无关的&#xff0c;例如Java应用程序等&#xff0c;它们对所运行的CPU平台没有依赖性&#xff0c;可以很好的适配当前平台进行执行。而在底层…

基于WEB的停车场管理系统的设计和实现【附源码】

基于WEB的停车场管理系统的设计和实现 摘 要 随着现代社会的快速发展&#xff0c;人民生活水平快速提高&#xff0c;汽车的数量飞速增加&#xff0c;与此同时停车问题也越来越受到人们的关注&#xff0c;为了实现对停车场进行有效的管理&#xff0c;结合一些停车场的模式和现状…

机器学习与计算机视觉 D2

整合为学习笔记&#xff01;参考阅读了几位大佬的作品&#xff0c;已标注出处~ 机器学习的数学基础 线性与非线性变换 从几何意义上&#xff0c;线性变换表示的是直线的特性&#xff0c;符合两个性质: 变换前后零点不变&#xff0c;变换前后直线还是直线。 线性变换意味着可以…

亚马逊美国站买家号注册流程

注册亚马逊美国站买家号一般用邮箱及手机号注册就可以了&#xff0c;具体操作如下&#xff1a; 1、在浏览器里面输入亚马逊美国站的官网地址。 2、点击注册&#xff0c;输入姓名、邮箱或手机号、密码&#xff0c;然后进行验证邮箱或者手机号。如果是用的邮箱进行注册验证&…

c语言上机作业:给函数增加防御机制

1.题目 2.思路 1.首先&#xff0c;我们可以知道&#xff0c;我们必须先要把z求出来&#xff0c;但这里需要注意的是x&#xff0c;y并不包含了全部的定义域&#xff0c;所以我们必须先判断是否输入的数据满足条件。而这&#xff0c;就是我们所需要突破的函数的防御&#xff0c;…

单链表——OJ题(一)

目录 ​一.前言 二.移除链表元素 三.返回链表中间节点 四.链表中倒数第K个节点 五.合并两个有序链表 六.反转链表 七.链表分割 八.链表的回文结构 九.相交链表 十.环形链表 十一.环形链表&#xff08;二&#xff09; ​六.结语 一.前言 本文主要对平时的链表OJ进行…

Vue2+Vue3

文章目录 第 1 章&#xff1a;Vue 核心1、 Vue 简介1.官网2.介绍与描述3. Vue 的特点4. 与其它 JS 框架的关联5. Vue 周边库 2、初始Vue3、模板语法1、Vue模板语法有2大类:2、插值语法和指令语法 4、数据绑定1. 单向数据绑定2. 双向数据绑定 5、el与data的两种写法1.e1有2种写法…

专访特斯拉工程师杨硕:跟着机器人上天入地、探索地外行星丨智源独家

导读 十几岁时&#xff0c;他痴迷《终结者》&#xff0c;曾在百科全书中窥见卡内基梅隆大学机械臂的介绍&#xff0c;从而得知了研究机器人「圣地」的存在。 在CMU&#xff0c;他深耕足式机器人感知定位算法&#xff0c;期待未来涉足太空&#xff0c;走上火星。 在大疆&#xf…

水果音乐制作软件FL Studio21.2中文版新功能介绍

FL Studio21.2中文版&#xff0c;一般又称水果音乐制作软件。 FL Studio 21.2简称FL&#xff0c;全称FruityLoopsStudio&#xff0c;因此国人习惯叫它"水果"。它让你的计算机就像是全功能的录音室&#xff0c;大混音盘&#xff0c;非常先进的制作工具&#xff0c;让…

【C语言】数据结构——栈和队列实例探究

&#x1f497;个人主页&#x1f497; ⭐个人专栏——数据结构学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读&#xff1a;一、 栈1. 栈的概念及结构2. 栈的实现3. 实现代码3.1 定义结构体3.2 初始化栈3.3 销毁栈3.4 入栈3.5 出栈…

java io流中为什么使用缓冲流就能加快文件读写速度

FileInputStream的read方法底层确实是通过调用JDK层面的read方法&#xff0c;并且这个JDK层面的read方法底层是使用C语言编写的&#xff0c;以实现高效的文件读取功能。但是它会涉及多次内核态与操作系统交互。当我们使用FileInputStream的read方法读取文件时&#xff0c;首先会…

微服务 Spring Cloud 8,开源RPC框架如何选型?

目录 一、开源RPC框架有哪些&#xff1f;1、跟语言平台绑定的开源RPC框架2、跨语言平台的开源RPC框架 二、跟语言平台绑定的开源RPC框架 -- Dubbo1、Dubbo的架构主要包含四个角色2、Dubbo的调用框架是如何实现的&#xff1f; 三、如何选择&#xff1f;四、跨语言平台的开源RPC框…

继承【C++】

继承【C】 一.什么是继承&#xff1f;二. 继承的方式与权限三. 继承中的成员3.0 基类和派生类中的重名成员i. 限定符ii. 隐藏 3.1 继承与默认成员函数i. 默认构造ii. 析构函数 3.2 继承与友元函数3.3 继承与静态成员变量 四. 基类和派生类的赋值五. 多继承5.1 菱形继承5.2 菱形…

CFCA证书——基于SM2/3算法的安全信任

在中国金融认证中心&#xff08;CFCA&#xff09;发行的证书中&#xff0c;采用了最新的国密SM2/3算法来提供更高的安全保障。这一创新举措进一步增强了我国网络安全能力&#xff0c;并为用户提供了一种更可靠、更安全的选择。 SM2/3算法是中国自主研发的非对称加密算法&#…

瑞格心理咨询系统设置多个管理员的操作方法

使用瑞格心理咨询系统&#xff0c;需要设置多个admin权限的管理员账号来管理&#xff0c;咨询厂家答复只能有1个管理员&#xff0c;个人觉得不可能&#xff0c;于是开始折腾。 解决办法&#xff1a; 在没有数据字典的情况下&#xff0c; 通过遍历数据库&#xff0c;发现用户信…