Linux---进程间通信(下)

1、System V 共享内存

原理如下图

 系统调用接口介绍

int shmget(key_t key, size_t size, int shmflg)

功能:用来创建共享内存
参数

  • key:这个共享内存段名字,内核用key来标识共享内存
  • size:共享内存大小
  • shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的(这里介绍两个:IPC_CREAT和IPC_EXCL,其中IPC_CREAT表示共享内存存在就返回,不存在就创建,IPC_EXCL不单独使用,IPC_EXCL | IPC_CREAT表示不存在就创建,存在就出错返回,作用是确保创建出来的共享内存一定是全新的)

返回值:成功返回一个非负整数,即该共享内存段的标识码(作用类似文件描述符fd);失败返回-1

void* shmat(int shmid, const void* shmaddr, int shmflg)

功能:将共享内存段连接到进程地址空间(在页表中创建映射关系)
参数

  • shmid:共享内存标识
  • shmaddr:指定连接的地址(可以直接传nullptr,让OS帮你分配)
  • shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY

返回值:成功返回一个指针,指向共享内存第一个节(类比malloc);失败返回-1

 int shmdt(const void *shmaddr)

功能:将共享内存段与当前进程脱离(删除页表中的映射关系)
参数

  • shmaddr:由shmat所返回的指针

返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段

int shmctl(int shmid, int cmd, struct shmid_ds *buf)

功能:用于控制共享内存
参数

  • shmid:由shmget返回的共享内存标识码
  • cmd:将要采取的动作(IPC_STAT---获取共享内存的相关信息、IPC_SET---设置共享内存的相关信息、IPC_RMID---释放共享内存)
  • buf:指向一个保存着共享内存的模式状态和访问权限的数据结构

返回值:成功返回0;失败返回-1

(共享内存的生命周期是随内核的,即进程结束,共享内存不会释放,需要手动释放空间)

 共享内存的通信代码如下

//comm.hpp#include <string>
#include <iostream>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <cstring>
using namespace std;// 路径和项目id可以随便写,但是建议写和代码相关的
string pathname = "/shm";
int process_id=0x11223344;const int size = 4096; // 建议设置为n*4096,Linux以4096为单位进行分配共享内存
string filename = "fifo"; //管道名,下面代码用管道是利用管道的同步机制,共享内存没有同步机制key_t Getkey()
{key_t key = ftok(pathname.c_str(), process_id);// 该系统调用相当于一个hash函数,用两个参数通过算法获得一个hash值 keyif(key < 0){cout << "errno: " << errno << ",errstring: " << strerror(errno) << endl;exit(1);}return key;
}string ToHex(int id) // 返回16进制表示形式 
{char buffer[1024];snprintf(buffer,sizeof(buffer),"0x%x",id);return buffer;
}int CreateShmHelper(key_t key, int flag)
{int shmid = shmget(key, size, flag);if(shmid < 0){cout << "errno: " << errno << ",errstring: " << strerror(errno) << endl;exit(2);}return shmid;
}int GetShm(key_t key)
{return CreateShmHelper(key, IPC_CREAT);
}int CreateShm(key_t key)
{return CreateShmHelper(key, IPC_CREAT|IPC_EXCL|0666);// 设置创建共享内存并设置权限0666---八进制
}//server.cc#include "comm.hpp"
//用一个类来初始化资源和释放资源
class Init
{
public:Init(){int n = mkfifo(filename.c_str(), 0666);if(n < 0) exit(1);key_t key = Getkey();cout << "key:" << ToHex(key) << endl;// sleep(5);// key vs shmid// key:内核中使用,标识共享内存的唯一性// shmid:应用这个共享内存的时候,我们使用shmid来使用操作共享内存// 即key是给内核看的,shmid是给用户看的shmid = CreateShm(key);cout << "shmid:" << shmid << endl;cout << "创建内存" << endl;p = (char*)shmat(shmid, nullptr, 0);cout << "将内存挂接到虚拟地址空间" << endl;sleep(3);
//注意资源的初始化顺序,管道的打开要放在恰当的地方,不然会出bug,这边建议放到最后fd = open(filename.c_str(), O_RDONLY);// 读端}~Init(){close(fd);unlink(filename.c_str());// 删除管道文件shmdt(p);cout << "删除页表映射" << endl;sleep(3);shmctl(shmid, IPC_RMID, nullptr);cout << "删除内存" << endl;}
public:int fd;int shmid;char*p;
};int main()
{Init init;int code = 0;while(1){ssize_t n = read(init.fd, &code, sizeof(code));if(n > 0){cout << "client:" << init.p << endl;}else if(n == 0){break;}}return 0;
}//client.cc
#include "comm.hpp"int main()
{key_t key = Getkey();cout << "key:" << ToHex(key) << endl;int shmid = GetShm(key);cout << "获取shmid:" << shmid << endl;char *p = (char *)shmat(shmid, nullptr, 0); // 开出来的空间当数组用即可cout << "挂接" << endl;int fd = open(filename.c_str(), O_WRONLY);int code = 1;cout << "write start" << endl;for (int i = 0; i < 26; i++){p[i] = 'a' + i;sleep(2);write(fd, &code, sizeof(code));cout << "write:" << (char)('a' + i) << endl;}shmdt(p);cout << "取消映射" << endl;return 0;
}

在看完上面这段代码的前提下,我们就能解释两个进程如何得到同一个共享内存的标识符:本质是我们事先约定了标识符key的值(在上面的代码中,我们是用ftok函数生成的key,使用的相同的参数,所以返回值也相同。这里使用ftok只是让系统帮助我们生成key,其实只要key这个值相对其他共享内存的key是唯一的即可),放在头文件中,然后两个程序通过key就能找到同一个共享内存

特点:

  • 共享内存的通信方式,不会提供同步机制,共享内存是直接裸露给所有的使用者的,一定要注意共享内存的使用安全问题
  • 共享内存可以提供较大的空间
  • 共享内存是所有进程间通信速度最快的(因为管道底层是对文件操作的复用,所以数据需要在用户缓冲区和内核文件缓冲区间来回拷贝,但是共享内存不需要,共享内存可以理解为用malloc申请了一块空间,两个进程都能看见,没有用户缓冲区和内核文件缓冲区来回拷贝的过程,所以更快)

查看管理ipc资源的指令介绍

 ipcs -m

ipcrm -m shmid   删除共享内存

2、System V 消息队列---简单介绍

消息队列提供一个进程给另一个进程发送数据块的能力

3、System V信号量---简单介绍

背景介绍

当我们在进行进程间通信的时候,可能会出现A进程和B进程通过同一份资源在进行通信,突然C进程也开始往该资源中写数据/读数据,导致数据传输出现问题的情况,换句话说,当多执行流访问同一份资源时,我们需要保护该资源,所以我们有了信号量这个概念

在介绍信号量的概念之前,我们先来看看信号量(semaphore)的系统调用接口

信号量的概念和理解

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

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

相关文章

AMRT3D数字孪生引擎详解

AMRT 3D数字孪生引擎介绍 AMRT3D引擎是一款融合了眸瑞科技的AMRT格式与轻量化处理技术为基础&#xff0c;以降本增效为目标&#xff0c;支持多端发布的一站式纯国产自研的CS架构项目开发引擎。 引擎包括场景搭建、UI拼搭、零代码交互事件、光影特效组件、GIS/BIM组件、实时数据…

矩阵的导数运算(理解分子布局、分母布局)

矩阵的导数运算(理解分子布局、分母布局) 1、分子布局和分母布局 请思考这样一个问题&#xff0c;一个维度为m的向量y对一个标量x的求导&#xff0c;那么结果也是一个m维的向量&#xff0c;那么这个结果向量是行向量&#xff0c;还是列向量呢&#xff1f; 答案是&#xff1a…

Spring及工厂模式概述

文章目录 Spring 身世什么是 Spring什么是设计模式工厂设计模式什么是工厂设计模式简单的工厂设计模式通用的工厂设计 总结 在 Spring 框架出现之前&#xff0c;Java 开发者使用的主要是传统的 Java EE&#xff08;Java Enterprise Edition&#xff09;平台。Java EE 是一套用于…

《Docker 简易速速上手小册》第3章 Dockerfile 与镜像构建(2024 最新版)

文章目录 3.1 编写 Dockerfile3.1.1 重点基础知识3.1.2 重点案例&#xff1a;创建简单 Python 应用的 Docker 镜像3.1.3 拓展案例 1&#xff1a;Dockerfile 优化3.1.4 拓展案例 2&#xff1a;多阶段构建 3.2 构建流程深入解析3.2.1 重点基础知识3.2.2 重点案例&#xff1a;构建…

港科夜闻|香港科大计划建立北部都会区卫星校园完善科大创新带,发展未来创新科技 未来医药发展及跨学科教育...

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大计划建立北部都会区卫星校园完善“科大创新带”&#xff0c;发展未来创新科技、未来医药发展及跨学科教育。香港科大校长叶玉如教授在2月22日的媒体会议上表示&#xff0c;香港科大将在北部都会区建立卫星校园&a…

open3d KD-Tree K近邻点搜索

open3d KD-Tree K近邻点搜索 一、算法原理1.KD-Tree 介绍2.原理 二、代码三、结果1.原点云2.k近邻点搜索后的点云 四、相关数据 一、算法原理 1.KD-Tree 介绍 kd 树或 k 维树是计算机科学中使用的一种数据结构&#xff0c;用于在具有 k 维的空间中组织一定数量的点。它是一个…

【Spring MVC】处理器映射器:AbstractHandlerMethodMapping源码分析

目录 一、继承体系 二、HandlerMapping 三、AbstractHandlerMapping 四、AbstractHandlerMethodMapping 4.1 成员属性 4.1.1 MappingRegistry内部类 4.2 AbstractHandlerMethodMapping的初始化 4.3 getHandlerInternal()方法&#xff1a;根据当前的请求url&#xff0c;…

从git上clone项目到本地后启动时的一种报错

当我们从git上拉项目到本地之后&#xff0c;先install,但启动时可能会出现报错&#xff0c;例如上面这种报错&#xff0c;这时候我们需要把package.json里的vite改一下&#xff0c;例如改成2.6.13&#xff0c;之后删掉node_modules,重新install,再启动一下&#xff0c;就好了。…

OT 安全解决方案:探索技术

IT 和 OT 安全的融合&#xff1a;更好的防御方法 OT 安全解决方案下一个时代&#xff1a; 为了应对不断升级的威胁形势&#xff0c;组织认识到迫切需要采用统一的信息技术 (IT) 和运营技术 (OT) 安全方法。IT 和 OT 安全的融合代表了一种范式转变&#xff0c;承认这些传统孤立领…

音频smmu问题之smmu学习

一、音频smmu 内存访问问题 在工作中&#xff0c;遇到一个smmu问题&#xff0c;主要log信息如下&#xff1a; arm-smmu 15000000.apps-smmu: Unhandled arm-smmu context fault from soc:spf_core_platform:qcom,msm-audio-ion! arm-smmu 15000000.apps-smmu: FAR 0x0000000…

什么是负载均衡集群?

目录 1、集群是什么&#xff1f; 2、负载均衡集群技术 3、负载均衡集群技术的实现 4、实现效果如图 5、负载均衡分类 6、四层负载均衡&#xff08;基于IP端口的负载均衡&#xff09; 7、七层的负载均衡&#xff08;基于虚拟的URL或主机IP的负载均衡) 8、四层负载与七层…

(3)(3.6) 用于OpenTX的Yaapu遥测脚本

文章目录 前言 1 安装和操作 2 参数说明 前言 这是一个开源 LUA 脚本&#xff0c;用于在使用 OpenTX 2.2.3 的 Horus X10、X12、Jumper T16、T18、Radiomaster TX16S、Taranis X9D、X9E、QX7 和 Jumper T12 无线电设备上显示 FrSky 的直通遥测数据(FrSky passthrough telem…

Linux配置jdk、tomcat、mysql离线安装与启动

目录 1.jdk安装 2.tomcat的安装&#xff08;开机自启动&#xff09; 3.MySQL的安装 4.连接项目 1.jdk安装 上传jdk安装包 jdk-8u151-linux-x64.tar.gz 进入opt目录&#xff0c;将安装包拖进去 解压安装包 这里需要解压到usr/local目录下&#xff0c;在这里我新建一个文件夹…

【Vue3】学习computed计算属性

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

NXP实战笔记(十):S32K3xx基于RTD-SDK在S32DS上配置CAN通信

目录 1、概述 2、SDK配置 2.1、配置目标 2.2、CAN配置 3、代码实现 4、测试结果 1、概述 S32K3xx的FlexCan与之前的S32K1xx很相似,Can的中断掩码寄存器(IMASK3)与中断标志位寄存器(IFLAG3)依赖于邮箱数。 FlexCan配置实例如下 FlexCan的整体图示如下 Protocol Engine…

PyTorch概述(六)---View

Tensor.view(*shape)-->Tensor 返回一个新的张量同之前的张量具有相同的数据&#xff0c;但是具有不同的形状&#xff1b;返回的张量同之前的张量共享相同的数据&#xff0c;必须具有相同数目的元素&#xff0c;可能具有不同的形状&#xff1b;对于经过view操作的张量&…

Python中操作MySQL和SQL Server数据库的基础与实战【第97篇—MySQL数据库】

Python中操作MySQL和SQL Server数据库的基础与实战 在Python中&#xff0c;我们经常需要与各种数据库进行交互&#xff0c;其中MySQL和SQL Server是两个常见的选择。本文将介绍如何使用pymysql和pymssql库进行基本的数据库操作&#xff0c;并通过实际代码示例来展示这些操作。…

Visual Studio:Entity设置表之间的关联关系

1、选择表并右键-》新增-》关联 2、设置关联的表及关联关系并“确定”即可

真的是性能优化(压测)-纯思想

文章目录 概要优化指标-MD都是文字看看就行性能优化操作1、代码优化&#xff1a;2、系统配置与环境优化&#xff1a;3、架构与设计&#xff1a;4、~~实施与监控&#xff1a;~~5、~~开发流程和环境管理&#xff1a;~~ 总结 概要 性能优化是一个持续的过程&#xff0c;需要监控、…

神经网络系列---感知机(Neuron)

文章目录 感知机(Neuron)感知机(Neuron)的决策函数可以表示为&#xff1a;感知机(Neuron)的学习算法主要包括以下步骤&#xff1a;感知机可以实现逻辑运算中的AND、OR、NOT和异或(XOR)运算。 感知机(Neuron) 感知机(Neuron)是一种简单而有效的二分类算法&#xff0c;用于将输入…