【进程间通信】共享内存

文章目录

  • 共享内存
    • 常用的接口
    • 指令
    • 利用命名管道实现同步机制
    • 总结

System V的IPC资源的生命周期都是随内核的。

共享内存

共享内存也是为了进程间进行通信的,因为进程间具有独立性,通信的本质是两个不同的进程看到同一份公共资源,所以共享内存一定是由OS提供的,共享内存的本质就是,在内存中开辟一块空间,然后映射在需要通过这片空间的进程的地空间中堆和栈之间共享区,通过这样的方式让两个不同的进程看到同一份公共资源。如下图:
在这里插入图片描述
一个共享内存可以满足很多进程进行通信,它可以挂载很多进程,但是OS中的进程是很多的,不同的进程和不同的进程之间需要通信的内容和方式也不太一样,所以OS中一定会存在大量的共享内存,因此OS一定要对共享内存进行管理(先描述,在组织),所以OS中一定有描述共享内存的各种属性的结构体,然后用链表等数据结构把OS中存在的共享内存管理起来,这样对共享内存的管理就变成了对链表的增删查改。
在这里插入图片描述

那么如何保证两个不同进程能看到同一个共享内存呢?
OS是让两个进程通过约定的方式让不同的进程看到同一块共享内存,两个进程约定一个key值,这个key值会被写入shm结构体中,然后不同的进程拿着相同的key值,就可以看到同一份共享内存了,但是系统中的共享内存会存在很多个,这个key值每个共享内存应该是不同的,所以我们需要尽可能的保证key的唯一性,但是让用户来进行这个操作,明显是不靠谱的,所以有个系统调用的函数,可以来帮助我们形成这个key值。
在这里插入图片描述
只需要传进去一个字符串和一个整型变量,这个函数就会通过自身的算法给我们形成一个key值,两个不同的进程拿着相同的字符串和相同的整型变量再通过相同的算法,形成的key值一定是一样的。这个key值最终是要被写进内核数据结构的。
在这里插入图片描述
这个__key就是我们用户自己传进去的key。共享内存 = 共享内存空间 + 共享内存属性

常用的接口

shmget
在这里插入图片描述
第一个参数就是我们之前自己形成的key,最后一个最常用的标志位就两个,IPC_CREAT和IPC_EXCL

  1. IPC_CREAT :不存在就创建,存在就获取
  2. IPC_EXCL:单独使用没有任何意义,和IPC_CREAT 一起使用,不存在就创建,存在就报错,这两个参数一起使用可以保证一定是第一次创建共享内存。

第三个参数的标志位后面可以直接跟共享内存的权限,具体可以参考下面的代码。

它的返回值就类似于文件描述符,方便用户操作,并且后面的节后都需要用这个shmid来标识自己创建的共享内存,我们的key是内核里面用的为了标识共享内存的唯一性,我们用户用的都是shmid,并且指令删除共享内存也是要用shmid不能使用key。

shmat
在这里插入图片描述
在这里插入图片描述

创建成功后,我们会拿到一个指针,这个指针就和malloc开辟的空间一样,可以直接拿着指针对这块内存进行操作。第二个参数我们一般为nullptr就行,最后一个参数一般为0。

shmdt
在这里插入图片描述

shmctl
在这里插入图片描述
在这里插入图片描述

指令

常用相关的函数就是这些,在Linux中如果我们要查看已经创建的共享内存有哪些,可以使用ipcs -m 指令
在这里插入图片描述
想要删除一个共享内存可以使用ipcrm -m shmid 的方式删除
在这里插入图片描述
最后的数字应该为具体的shmid。

利用命名管道实现同步机制

共享内存不会提供同步机制,但是他是需要同步机制的,我们可以使用管道来实现它的同步机制,接下来我们可以利用前面的命名管道尝试实现一下这个同步机制。

我们需要两个独立的进程一个server,一个client,所以我们需要一个可以形成两个可执行程序的Makefile。

.PHONY:all
all:client serverclient:Client.ccg++ -o $@ $^ -std=c++11server:Server.ccg++ -o $@ $^ -std=c++11.PHONY:clean
clean:rm -rf client server

然后我们需要一个Client.cc和Server.cc,但是我们需要形成同一个key,所以我们可以把两个源文件中需要两个进程看到的同一份资源抽出来,Com.hpp。

Com.hpp

#pragma once
#include <iostream>
#include <string>
#include <cerrno>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>const std::string path = "/home/ysl/long/class_dragon/test_5_8/shm";
const std::string filename = "fifo";
const int proj_id = 0x11223344;
const int num = 4096;key_t getkey()
{key_t key = ftok(path.c_str(), proj_id);if(key < 0){std::cerr << "getkey error" << std::endl;exit(-1);}return key;
}int _getshm(key_t key, int flag)
{int shmid = shmget(key,num,flag);if(shmid < 0){std::cerr << "shm error" << std::endl;exit(-1);}return shmid;
}   int Create_shm(key_t key)
{return _getshm(key,IPC_CREAT|IPC_EXCL|0644);
}int getshm(key_t key)
{return _getshm(key,IPC_CREAT);
}bool Create_fifo()
{int n = mkfifo(filename.c_str(),0666);if(n < 0){std::cerr << "mkfifo error" << std::endl;return false;}return true;
}

Server.cc

#include "Com.hpp"class Init
{
public:Init(){//创建命名管道Create_fifo();// 获取keykey_t key = getkey();// 创建共享内存shmid = Create_shm(key);std::cout << shmid << std::endl;std::cout << "chuangjian" << std::endl;// 挂载addr = (char *)shmat(shmid, nullptr, 0);std::cout << "guazai" << errno << std::endl;fd = open(filename.c_str(),O_RDONLY);}~Init(){shmdt(addr);std::cout << "qu" << std::endl;// 删除共享内存shmctl(shmid, IPC_RMID, nullptr);std::cout << "shan" << std::endl;close(fd);unlink(filename.c_str());}public:int shmid;char *addr;int fd;
};Init init;
int main()
{while(true){int code = 0;ssize_t n = read(init.fd,&code,sizeof code);if(n > 0){std::cout << init.addr << std::endl;}else if(n == 0){break;}//sleep(1);}return 0;
}

Client.cc

#include "Com.hpp"class Init
{
public:Init(){// 获取keykey_t key = getkey();// 创建共享内存shmid = getshm(key);// 挂载addr = (char *)shmat(shmid, nullptr, 0);}~Init(){shmdt(addr);}public:int shmid;char *addr;
};Init init;int main()
{int fd = open(filename.c_str(),O_WRONLY);for(char ch = 'a'; ch <= 'z'; ++ch){int code = 1;write(fd,&code,sizeof code);init.addr[ch-'a'] = ch;sleep(1);}return 0;
}

我们是可以通过命名管道让共享内存拥有同步机制的。

总结

  1. 共享内存的通信方式,不会提供同步机制,共享内存是直接裸露给所有的使用者的,所以一定要注意共享内存的使用安全问题。
  2. 共享内存可以提供较大的空间。
  3. 共享内存是所有进程间通信中速度最快的。可以减少数据拷贝的次数。

为什么说共享内存是最快的?
这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据,也就会减少很多的数据的拷贝。

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

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

相关文章

Java 11 到 Java 8 的兼容性转换

Java 11 到 Java 8 的兼容性转换 欲倚绿窗伴卿卿&#xff0c;颇悔今生误道行。有心持钵丛林去&#xff0c;又负美人一片情。 静坐修观法眼开&#xff0c;祈求三宝降灵台&#xff0c;观中诸圣何曾见&#xff1f;不请情人却自来。 入山投谒得道僧&#xff0c;求教上师说因明。争奈…

WordPress MasterStudy LMS插件 SQL注入漏洞复现(CVE-2024-1512)

0x01 产品简介 WordPress和WordPress plugin都是WordPress基金会的产品。WordPress是一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。WordPress plugin是一个应用插件。 0x02 漏洞概述 WordPress Plugin MasterStudy LMS 3.2.5 版本及之…

java项目之在线课程管理系统源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的在线课程管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 在线课程管理系统的主要…

Nginx配置/.well-known/pki-validation/

当你需要在Nginx上配置.well-known/pki-validation/时&#xff0c;这通常是为了支持SSL证书的自动续订或其他验证目的。以下是配置步骤&#xff1a; 创建目录结构&#xff1a; 在你的网站根目录下创建一个名为.well-known的目录&#xff08;SSL证书申请之如何创建/.well-known/…

Linux环境Redis部署

Redis部署 Redis是一个高性能的开源键值存储系统&#xff0c;它主要基于内存操作&#xff0c;但也支持数据的持久化。与其他数据库相比&#xff0c;Redis的主要优势在于它的高性能、丰富的数据结构和原生的持久化能力。Redis不仅提供了类似的功能&#xff0c;还增加了持久化和…

[初阶数据结构】单链表

前言 &#x1f4da;作者简介&#xff1a;爱编程的小马&#xff0c;正在学习C/C&#xff0c;Linux及MySQL。 &#x1f4da;本文收录于初阶数据结构系列&#xff0c;本专栏主要是针对时间、空间复杂度&#xff0c;顺序表和链表、栈和队列、二叉树以及各类排序算法&#xff0c;持…

如何使用client-go构建pod web shell

代码示例及原理 原理是利用websocket协议实现对pod的exec登录&#xff0c;利用client-go构造与远程apiserver的长连接&#xff0c;将对pod容器的输入和pod容器的输出重定向到我们的io方法中&#xff0c;从而实现浏览器端的虚拟终端的效果消息体结构如下 type Connection stru…

Meta更低的训练成本取得更好的性能: 多token预测(Multi-Token Prediction)

Meta提出了一种透过多token预测(Multi-token Prediction)来训练更好、更快的大型语言模型的方法。这篇论文的重点如下: 训练语言模型同时预测多个未来的token,可以提高样本效率(sample efficiency)。 在推论阶段,使用多token预测可以达到最高3倍的加速。 论文的主要贡献包括: …

ES集群数据备份与迁移

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、文章涉及概念讲解二、操作步骤1.创建 snapshot repository操作主机hadoop1分别操作从机hadoop2和hadoop3 2. 查看仓库信息3. 备份索引&#xff0c;生成快照…

【S32K UDS BootLoader】-1.1-Unified bootloader Demo和ECUBus工具的使用

<--返回「Autosar_MCAL高阶配置」专栏主页--> 目录 1 下载S32K1/S32K3/S12Z Unified bootloader Demo 1.1 在S32DS中编译S32K312_CAN_bootloader_RTD2d0工程并烧录 2 ECUBus工具使用 2.1 PCAN环境搭建 1.1.1 安装PCAN驱动 1.1.2 安装PCAN-View 2.2 下载并安装ECU…

C语言 | Leetcode C语言题解之第77题组合

题目&#xff1a; 题解&#xff1a; int** combine(int n, int k, int* returnSize, int** returnColumnSizes) {int* temp malloc(sizeof(int) * (k 1));int tempSize 0;int** ans malloc(sizeof(int*) * 200001);int ansSize 0;// 初始化// 将 temp 中 [0, k - 1] 每个…

回答篇:测试开发高频面试题目

引用之前文章&#xff1a;《测试开发高频面试题目》 https://blog.csdn.net/qq_41214208/article/details/138193469?spm1001.2014.3001.5502 本篇文章是回答篇&#xff08;持续更新中&#xff09; 1. 什么是测试开发以及其在软件开发流程中的作用。 a. 测试开发是指测试人员或…

关于Anaconda常用的命令

常用命令 查看当前环境下的环境&#xff1a;conda env list查看当前conda的版本&#xff1b;conda --version conda create -n your_env_name pythonX.X&#xff08;2.7、3.6等)命令创建python版本为X.X。名字为your_env_name的虚拟环境。your_env_name文件可以在Anaconda安装…

收银系统源码--什么是千呼智慧新零售系统?

千呼智慧新零售系统是一套针对零售行业线上线下一体化收银系统。给门店提供线下称重收银、o2o线上商城、erp进销存、精细化会员管理、丰富营销插件等一体化解决方案。多端数据打通&#xff0c;实现线上线下一体化&#xff0c;提升门店工作效率&#xff0c;实现数字化升级&#…

前端项目加载离线的百度地图,利用工具进行切指定区域的地图影像,自定义图层getTilesUrl

百度地图在开发中我们经常使用&#xff0c;但是有些项目是需要在内网进行&#xff0c;这时候我们不得不考虑项目中一些功能需要请求外网静态资源&#xff0c;比如百度地图。只有把包下载到本地&#xff0c;才能让静态资源文件的正常的访问。 目录 获取百度地图开发秘钥 引入在…

Java | Leetcode Java题解之第78题子集

题目&#xff1a; 题解&#xff1a; class Solution {List<Integer> t new ArrayList<Integer>();List<List<Integer>> ans new ArrayList<List<Integer>>();public List<List<Integer>> subsets(int[] nums) {dfs(0, nums…

牛客网刷题 | BC81 KiKi求质数个数

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 KiKi知道了什么是质…

【离散数学】集合上二元关系性质判定的实现(c语言实现)

实验要求 关系矩阵的初始化和打印 我们将关系矩阵存入一个二维数组中&#xff0c;因为集合元素个数不会超过5个所以就用一个5行5列二维数组来表示。 在我们得到了集合元素个数之后我们就可以对数组进行0,1随机赋值 //初始关系矩阵 void init_matrix(int array[][5], int n) {…

多核DSP并行计算跨平台通信解决方案

并行计算的核心是计算节点以及节点间的通信与协调机制。OpenMP虽然给开发者提供了极易上手的增量式开发方式&#xff0c;但是OpenMP在与复杂架构的MCSDK结合后&#xff0c;工具与代码产生了大量不可调试的黑盒子&#xff0c;更是决定了它不能用于关键任务领域&#xff0c;如军工…

算法学习Day2——单调栈习题

第一题&#xff0c;合并球 题解&#xff1a;一开始写了一次暴力双循环&#xff0c;直接O(n^2)严重超时&#xff0c;后面于是又想到了O(n)时间复杂度的链表&#xff0c;但是还是卡在 最后一个数据会TLE&#xff0c;我也是高兴的拍起来安塞腰鼓和华氏护肤水&#xff0c;后面学长给…