当前位置: 首页 > news >正文

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)信号队列&#xff08;Message Queue&#xff09;信号量(semaphore) 进程间通信的核心理念&#xff1a;让不同的进程看见同一块资源 linux下的通信方案&#xff1a; SYSTEM V 共享内存(Share Memory) 特点&#xff1a;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、分布式、队列模型的开源消息中间件&#xff0c;前身是MetaQ&#xff0c;是阿里参考Kafka特点研发的一个队列模型的消息中间件&#xff0c;后开源给apache基金会成为了apache的顶级开源项目&#xff0c;具有高性能、高可靠、高实时、分布式特点。 环境搭…...

【Web】关于FastJson反序列化开始前的那些前置知识

目录 FastJson介绍 FJ序列化与反序列化方法 关于反序列化三种方式的关系与区别 FastJson反序列化漏洞原理通识 关于getter&setter FastJson介绍 FastJson&#xff08;快速JSON&#xff09;是一个Java语言编写的高性能、功能丰富且易于使用的JSON解析和序列化库。它由…...

工业镜头的重要参数之视场、放大倍率、芯片尺寸--51camera

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

基于java springboot+redis网上水果超市商城设计和实现以及文档

基于java springbootredis网上水果超市商城设计和实现以及文档 博主介绍&#xff1a;多年java开发经验&#xff0c;专注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证书值得考虑?

为了确保网站数据传输安全&#xff0c;启用HTTPS加密是关键步骤。在众多SSL证书供应商中&#xff0c;如何找到价格合理且品质优良的HTTPS加密证书呢&#xff1f;本文将探讨这个问题&#xff0c;并重点关注具有高性价比优势的沃通CA。 沃通CA作为业内知名的SSL证书服务商&#x…...

R语言及其开发环境简介

R语言及其开发环境简介 R 语言历史 R 语言来自 S 语言&#xff0c;是 S 语言的一个变种。S语言由贝尔实验室研究开发&#xff0c;著名的 C 语言、Unix 系统也是贝尔实验室开发的。R 属于 GNU 开源软件&#xff0c;最初发布于1997年&#xff0c;实现了与 S 语言基本相同的功能…...

部署DNS解析服务

一、安装软件&#xff0c;关闭防火墙&#xff0c;启动服务 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函数后&#xff0c;寻优速度真的大幅度提升&#xff01;数据量大的不妨都试试这个官方的VMD函数。当然要下载2020a以上的MATLAB才可以哦&#xff01; 同样以西储大学数据集为例&#xff0c;选…...

自定义注解校验

在日常开发中经常会用到String类型的数据当作数值进行映射&#xff0c;势必会做出数值范围的校验&#xff0c;可以通过自定义注解的办法简化代码实现&#xff0c;减少冗余代码。 Target({ElementType.FIELD}) Retention(RetentionPolicy.RUNTIME) Constraint(validatedBy St…...

由数据范围反推算法复杂度以及算法内容

一般ACM或者笔试题的时间限制是1秒或2秒。 在这种情况下&#xff0c;C代码中的操作次数控制在 1 0 7 ∼ 1 0 8 10^7\sim10^8 107∼108为最佳。 下面给出在不同数据范围下&#xff0c;代码的时间复杂度和算法该如何选择&#xff1a; n ≤ 30 n\leq30 n≤30&#xff0c;指数级别…...

js监听F11触发全屏事件

当用户使用 F11 键进行浏览器全屏时&#xff0c;由于此时并非通过浏览器提供的 Fullscreen API 进入全屏模式&#xff0c;因此无法通过 fullscreenchange 事件来监听全屏状态的变化。在这种情况下&#xff0c;可以通过监听 resize 事件来检测浏览器窗口大小的变化&#xff0c;从…...

Seata 2.x 系列【1】专栏导读

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Spring Boot 版本 3.1.0 本系列Seata 版本 2.0.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 背景2. 简介3. 适用人群4. 环境及版本5. 文章导航5…...

fly-barrage 前端弹幕库(3):滚动弹幕的设计与实现

项目官网地址&#xff1a;https://fly-barrage.netlify.app/&#xff1b; &#x1f451;&#x1f40b;&#x1f389;如果感觉项目还不错的话&#xff0c;还请点下 star &#x1f31f;&#x1f31f;&#x1f31f;。 Gitee&#xff1a;https://gitee.com/fei_fei27/fly-barrage&a…...

Mysql面试总结

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

【深圳五兴科技】Java后端面经

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

画图(ccf201409-2)解题思路

解题思路 填充100*100二维数组&#xff0c;范围内的元素修改成1&#xff0c;最后累积求和。...

蓝桥杯刷题(一)

一、 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))…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准

城市路内停车管理常因行道树遮挡、高位设备盲区等问题&#xff0c;导致车牌识别率低、逃费率高&#xff0c;传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法&#xff0c;正成为破局关键。该设备安装于车位侧方0.5-0.7米高度&#xff0c;直接规避树枝遮…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...