linux的通信方案(SYSTEM V)
文章目录
- 共享内存(Share Memory)
- 信号队列(Message Queue)
- 信号量(semaphore)
进程间通信的核心理念:让不同的进程看见同一块资源
linux下的通信方案: SYSTEM V
共享内存(Share Memory)
特点:1.共享内存是进程见通信最最快的
2.可以提供较大通信空间
注意:共享内存由于裸露给所有使用者,因此是需要维护的
做法:去申请一块空间,让其映射到对应的不同进程的进程地址空间。
如图:
那么具体是怎么做的呢?
- linux是生成一个特定的key,有key作为表示这块共享内存的唯一标识。
- 不同进程在运行的时候凭借这个key拿到共享内存的shmid(类似于文件管理系统的fd),进行挂接到自己的进程地址空间上。
- 申请的空间是不会自己释放的,要么在程序里面用funtion控制,要么在外部手动释放
-
ipcs -m
-
#查看当前有哪些共享内存
-
ipcrm -m shmid
-
#删除对应的共享内存id
需要用到的系统调用:
shmget #创建共享内存
shmat # 挂接共享内存
shmdt # 取消挂接
shmctl # 操控这块共享内存
unlink # 删除文件
server:
#include "Common.hpp"class Init
{
public:Init(){bool r = MakeFifo();//用管道是为了进程进行时,具备一定顺序性。if (!r)return;key_t key = GetKey();shmid = CreatShm(key);std::cout << "shmid:" << shmid << "\n";// sleep(5);std::cout << "开始将shm映射到进程地址空间\n";s = (char *)shmat(shmid, nullptr, 0);fd = open(filename.c_str(), O_RDONLY);}~Init(){close(fd);std::cout << "将shm从进程地址空间移除\n";shmdt(s);std::cout << "将共享内存从操作系统中释放\n";shmctl(shmid, IPC_RMID, nullptr);unlink(filename.c_str());}int FileDirection(){return fd;}const char *ShnPtr(){return s;}private:int shmid;int fd;char *s;
};int main()
{Init init;// struct shmid_ds ds;// std::cout<<std::hex<<ds.shm_perm.__key<<"\n";// std::cout<<ds.shm_nattch<<"\n";while (true){int code = 0;ssize_t n = read(init.FileDirection(), &code, sizeof(code));if (n > 0){std::cout << "共享读取:" << init.ShnPtr() << "\n";}else if (n == 0){break;}else{std::cerr << "读取错误,错误码:" << errno << "\n";}}return 0;
}
client
#include "Common.hpp"int main()
{key_t key = GetKey();int shmid = CreatShmHelper(key, IPC_CREAT | 0644);char *s = static_cast<char *>(shmat(shmid, nullptr, 0));std::cout << "attach shm done\n";int fd = open(filename.c_str(), O_WRONLY);for (int c = 0; c < 26; c++){s[c] = c + 'a';std::cout << "write:" << (char)c + 'a' << "done\n";sleep(1);int code = 1;write(fd, (char *)&code, sizeof(code));}// sleep(5);std::cout << "dettach shm done\n";shmdt(s);close(fd);return 0;
}
.h
#pragma once#include <iostream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <cassert>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>const std::string pathname = "./Common.hpp";//这里选择一起的头文件作为生成Key的路径文件即可
const int proj_id = 0x234;
const int size = 4096;
const std::string filename = "fifo";
key_t GetKey()
{key_t key = ftok(pathname.c_str(), proj_id);if (key < 0){std::cerr << "errno:" << errno << ",errnostring:" << std::strerror(errno) << std::endl;exit(-1);}return key;
}int CreatShmHelper(key_t key, int flag)
{int shmid = shmget(key, size, flag); //共享内存也有权限也是需要设置的// EXCL保证创建时如果存在就会失败if (shmid < 0){std::cerr << "errno:" << errno << ",errnostring:" << std::strerror(errno) << std::endl;exit(2);}return shmid;
}int CreatShm(key_t key)
{return shmget(key, size, IPC_CREAT | IPC_EXCL | 0644); //共享内存也有权限也是需要设置的
}int GetShm(key_t key)
{return shmget(key, size, IPC_CREAT); //共享内存也有权限也是需要设置的
}//为1创建成功
bool MakeFifo()
{int n = mkfifo(filename.c_str(), 0666);if (n < 0){std::cerr << "errno:" << errno << ",errstring" << strerror(errno) << std::endl;return 0;}std::cout << "mkfifo success..." << std::endl;return 1;
}
信号队列(Message Queue)
基于SYSTEM V的还有对应的信号队列(Message Queue),信号量
下面展示下Message Queue的简单使用代码。
基本的系统调用函数,在下面代码中有,具体使用可以通过man手册查询。
#pragma once#include <iostream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <cassert>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <sys/msg.h>
key_t GetKey()
{key_t key = ftok(pathname.c_str(), proj_id);if (key < 0){std::cerr << "errno:" << errno << ",errnostring:" << std::strerror(errno) << std::endl;exit(-1);}return key;
}//消息队列也是存在于内核之中,不手动关闭的生命周期和内核一起int main()
{key_t key = GetKey();int msgid = msgget(key,IPC_CREAT |IPC_EXCL);std::cout<<"msgid:"<<msgid<<'\n';struct msqid_ds ds;std::cout<<ds.__msg_cbytes<<'\n';std::cout<<ds.msg_perm.__key<<'\n';//用msgsend来发送消息//用msgrcv来接受消息msgctl(msgid,IPC_RMID,nullptr);//也可以 ipcrm -q msgid 在bash删除return 0;}
信号量(semaphore)
前置知识:
- 公共资源:多个执行流看见的同一份资源
- 多个执行流访问同一份资源,就存在并发访问
- 为了解决并发访问公共资源的问题,导致的数据不一致、脏读等问题,需要保护资源
- 因此引发出互斥和同步
- 互斥:同一时刻,只能有一个执行流访问资源,加锁完成
- 同步:多个执行流按照预定的先后次序来访问公共资源
- 被保护起来的资源,称为临界资源
- 访问临界资源的执行流(或者代码),称为临界区
分析: - 本质是个计数器
- 当进程需要访问公共资源,先获取信号量,再去访问资源。(相当于信号量是获取资源的凭证,有了信号量,就一定会有资源)没获取信号量的进程,就阻塞等待。
- 信号量如果被获取了,就没了,没被获取,就全部都在。是只有两种状态,二元性的。因此由此二元性,完成了互斥的功能
- 不同的进程也需要看到同一份信号量,因此信号量也被纳入IPC体系,也就是说,信号量由操作系统提供
- 我们知道SYSTEM V的资源是可以看见的,但是信号量是原子的(atomic,不可在分的),即使被进程竞争的访问,也只会出现要么获取了,要么没获取信号量。不会出现获取半个的情况。这种原子的获取操作称之为P操作。相对应原子的释放,称之为V操作。
信号量系统调用
semget
semctl
semop
linux内核看SYSTEM V设计的共享内存等通信方式
一般来说:
- 内核里面有一个ipc_id_ary,其是一个柔性数组,存储了一个size表示大小和指针数组,size表示指针数组的个数
- 这个指针数组所存的指针类型是 **kern_ipc_perm***的指针类型
- 由SYSTEM V标准下设计出来的共享内存,信号队列等,内核里面都是由一个自己类型的结构体去管理的(例如:msg_queue,就是管理信号队列的结构体,Shmid_Kernel, 就是管理共享内存的结构体)
- 而这些结构体的第一个元素,都被设计成相似的结构体(信号队列是:q_perm,共享内存是:shm_perm),这些结构体所包含的元素类型,其实和 kern_ipc_perm的结构体元素类型是一样的。
- 这就使得我们存储kern_ipc_perm的指针,即使存了msg_queue的结构体指针,只需要通过强制类型转换,也是可以访问msg_queue结构体
- 这样对SYSYTEM V设计下的共享内存,信号队列等可以统一管理
上面这种内核的设计:实际就是利用了C语言的特点,实现了多态,有种通过父类指针访问子类的类似
相关文章:

linux的通信方案(SYSTEM V)
文章目录 共享内存(Share Memory)信号队列(Message Queue)信号量(semaphore) 进程间通信的核心理念:让不同的进程看见同一块资源 linux下的通信方案: SYSTEM V 共享内存(Share Memory) 特点:1.共享内存是进程见通信最…...
VUE 入门及应用 ( 路由 router )
6.前端路由 router Vue Router | Vue.js 的官方路由 (vuejs.org) 官方地址 : https://router.vuejs.org/zh/ 6.1.基本配置 6.1.0.准备 MyPage.vue 创建 用于测试 vue文件 ../views/MyPage.vue <template><div><h1>MyPage</h1></div> </…...

SpringBoot集成RocketMQ
RocketMQ是一个纯Java、分布式、队列模型的开源消息中间件,前身是MetaQ,是阿里参考Kafka特点研发的一个队列模型的消息中间件,后开源给apache基金会成为了apache的顶级开源项目,具有高性能、高可靠、高实时、分布式特点。 环境搭…...
【Web】关于FastJson反序列化开始前的那些前置知识
目录 FastJson介绍 FJ序列化与反序列化方法 关于反序列化三种方式的关系与区别 FastJson反序列化漏洞原理通识 关于getter&setter FastJson介绍 FastJson(快速JSON)是一个Java语言编写的高性能、功能丰富且易于使用的JSON解析和序列化库。它由…...

工业镜头的重要参数之视场、放大倍率、芯片尺寸--51camera
今天来简单介绍下工业镜头中常用的参数中的三个: 1、视场 视场(FOV)也称视野,是指能被视觉系统观察到的物方可视范围。 对于镜头而言,可观察到的视场跟镜头放大倍率及相机芯片选择有关。因此需要根据被观察物体的尺寸ÿ…...

基于java springboot+redis网上水果超市商城设计和实现以及文档
基于java springbootredis网上水果超市商城设计和实现以及文档 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留…...

3. 在Go语言项目中使用Zap日志库
文章目录 一、介绍二、 默认的Go Logger1. 实现Go Logger2. 设置Logger3. 使用Logger4. Logger的运行5. Go Logger的优势和劣势 三、Uber-go Zap1. 为什么选择Uber-go zap2. 安装3. 配置Zap Logger4. 定制logger4.1 将日志写入文件而不是终端4.2 将JSON Encoder更改为普通的Log…...

想要节省成本,哪个品牌的https证书值得考虑?
为了确保网站数据传输安全,启用HTTPS加密是关键步骤。在众多SSL证书供应商中,如何找到价格合理且品质优良的HTTPS加密证书呢?本文将探讨这个问题,并重点关注具有高性价比优势的沃通CA。 沃通CA作为业内知名的SSL证书服务商&#x…...
R语言及其开发环境简介
R语言及其开发环境简介 R 语言历史 R 语言来自 S 语言,是 S 语言的一个变种。S语言由贝尔实验室研究开发,著名的 C 语言、Unix 系统也是贝尔实验室开发的。R 属于 GNU 开源软件,最初发布于1997年,实现了与 S 语言基本相同的功能…...

部署DNS解析服务
一、安装软件,关闭防火墙,启动服务 1.yum install -y bind bind-utils bind-chroot 2.systemctl stop firewalld && setenforce 0 3.systemctl start named 二、工作目录 /var/named/chroot/etc #存放主配置文件 /var/named/chroot/var/n…...

2024新算法:鹅算法优化VMD参数,五种适应度函数任意切换,最小包络熵、样本熵、信息熵、排列熵、排列熵/互信息熵...
本期采用鹅算法优化一下VMD参数。利用MATLAB官方自带的VMD函数。 替换为官方自带的VMD函数后,寻优速度真的大幅度提升!数据量大的不妨都试试这个官方的VMD函数。当然要下载2020a以上的MATLAB才可以哦! 同样以西储大学数据集为例,选…...
自定义注解校验
在日常开发中经常会用到String类型的数据当作数值进行映射,势必会做出数值范围的校验,可以通过自定义注解的办法简化代码实现,减少冗余代码。 Target({ElementType.FIELD}) Retention(RetentionPolicy.RUNTIME) Constraint(validatedBy St…...
由数据范围反推算法复杂度以及算法内容
一般ACM或者笔试题的时间限制是1秒或2秒。 在这种情况下,C代码中的操作次数控制在 1 0 7 ∼ 1 0 8 10^7\sim10^8 107∼108为最佳。 下面给出在不同数据范围下,代码的时间复杂度和算法该如何选择: n ≤ 30 n\leq30 n≤30,指数级别…...
js监听F11触发全屏事件
当用户使用 F11 键进行浏览器全屏时,由于此时并非通过浏览器提供的 Fullscreen API 进入全屏模式,因此无法通过 fullscreenchange 事件来监听全屏状态的变化。在这种情况下,可以通过监听 resize 事件来检测浏览器窗口大小的变化,从…...
Seata 2.x 系列【1】专栏导读
有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列Seata 版本 2.0.0 源码地址:https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 背景2. 简介3. 适用人群4. 环境及版本5. 文章导航5…...

fly-barrage 前端弹幕库(3):滚动弹幕的设计与实现
项目官网地址:https://fly-barrage.netlify.app/; 👑🐋🎉如果感觉项目还不错的话,还请点下 star 🌟🌟🌟。 Gitee:https://gitee.com/fei_fei27/fly-barrage&a…...

Mysql面试总结
基础 1. 数据库的三范式是什么? 第一范式:强调的是列的原子性,即数据库表的每一列都是不可分割的原子数据项。第二范式:要求实体的属性完全依赖于主关键字。所谓完全 依赖是指不能存在仅依赖主关键字一部分的属性。第三范式&…...

【深圳五兴科技】Java后端面经
本文目录 写在前面试题总览1、java集合2、创建线程的方式3、对spring的理解4、Spring Boot 和传统 Spring 框架的一些区别5、springboot如何解决循环依赖6、对mybatis的理解7、缓存三兄弟8、接口响应慢的处理思路9、http的状态码 写在前面 关于这个专栏: 本专栏记录…...

画图(ccf201409-2)解题思路
解题思路 填充100*100二维数组,范围内的元素修改成1,最后累积求和。...

蓝桥杯刷题(一)
一、 import os import sys def dps(s):dp [0] * len(s)dp[0] ord(s[0]) - 96if len(s) 1:return dp[-1]dp[1] max(ord(s[0]) - 96, ord(s[1]) - 96)for i in range(2, len(s)):dp[i] max(dp[i - 1], dp[i - 2] (ord(s[i])) - 96)return dp[-1] s input() print(dps(s))…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...