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

systemV的工作原理+原理代码

概念

我们知道进程间的通信有管道的方式进程通信管道制作_云的小站的博客-CSDN博客

但是我们的管道通信其实属于一种取巧的方式,利用了打开的文件可读写的特性上,两个进程对此分别进行读写操作就会产生所谓的通信现象,但是外面的管道依旧得再磁盘上创建一个文件,然后文件打开加载在内存上才可以使用,那么有什么方法可以直接加载在内存,而无需对磁盘操作呢?

---------利用systemV共享内存通信

利用系统函数shmget在内存中开辟一块空间用于进程通信的交互点。因为两个进程之间不可以直接通信,所以需要加一个中间层。

 

学计算机,当两个东西不通的时候,我们最经常干的事情就是加一个中间层,既保护了独立性,又处理了我们需要完成的事情

工具

shmget(创建共享内存)

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

 返回值:

失败返回-1,成功返回一个shmid唯一的共享内存标识符。

key:

唯一值,两个进程需要同一个key值才可以访问到同一共享内存空间。

size:

设置共享内存大小

shmflg

共享内存创建选项,IPC_CREAT | IPC_EXCL|0666 

IPC_CREAT:如果内存存在key标识符的共享内存直接使用,如果不存在就创建

IPC_EXCL:如果内存存在key标识符的共享内存直接失败退出。

0666:共享内存的使用权限。

shmctl(操作共享内存)

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

返回值:

如果操作成功返回0,操作失败返回-1;

shmid:

对该shmid的共享内存进行操作;

cmd:

对共享内存的操作选项,一般我们删除共享内存用的使用:IPC_RMID

buf:

获取该共享内存的数据结构地址。(共享内存也需要被描述组织)。

shmat(进程的挂接操作)

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

返回值:

成功返回共享内存的地址,失败返回-1,并设置errno错误原因。

shmid:

挂接在shmid标识符的共享内存上。

shmaddr:

理论上可以自己设置将共享内存挂接在自己指定的位置,但是不建议。所以一般设置为nullptr,

shmflg

设置访问方式只读、只写等等。设置为0,读写操作。

shmdt(进程的拆除操作)

int shmdt(const void *shmaddr);

返回值:

成功拆除返回0,失败返回-1;

shmaddr:

将进程地址空间shmaddr的共享内存,进行拆除。

ftok(生成一个key值为shmget服务)

key_t ftok(const char *pathname, int proj_id);

返回值:

返回有个随机数字。

pathname:

传一个文件路径,使用文件的inode值,对了文件必须要有访问权限。

proj_id:

项目id,0~255,其实可以随便写,会截断。

ps:ftok不进行系统调用,他只是一个算法

代码

来来来,工具说完了直接上代码:

头文件

日志+需要的接口

日志

  1 #ifndef _LOG_H_2 #define _LOG_H_3 #include <ctime>4 #include <iostream>5 6 #define Debug 07 #define Notice 18 #define Warning 29 #define Error 310 11 std::string mgs[] = {12     "Debug",13     "Notice",14     "Warning",15     "Error"};16 17 std::ostream &Log(std::string message, int level)18 {19     std::cout << " | " << (unsigned)time(nullptr)20     << " | " << mgs[level] << " | "<<message;21     return std::cout;                                                                                                           22 }23 24 #endif
~

所需头文件

 1 #pragma once                                                                                                                    2 #include<iostream>3 #include<cstdio>4 #include<sys/shm.h>5 #include<sys/ipc.h>6 #include<sys/types.h>7 #include"Log.hpp"8 #include<assert.h>9 #include<unistd.h>10 using namespace std;11 #define SIZE 409612 #define PATH_NAME "."13 #define PROJ_ID 0x6614 15 16 string TransToHex(key_t k)17 {18     char buffer[32];19     snprintf(buffer,sizeof(buffer),"0x%x",k);20     return buffer;21 }

接收方代码

#include"comm.hpp"2 3 int main()4 {5     // 1.创建公共key6     key_t k=ftok(PATH_NAME,PROJ_ID);7     assert(k!=-1);8     Log("create key done",Debug)<<" sgmrevice key: "<< TransToHex(k)<<endl;9     sleep(10);10     //2.创建共享内存11 12     int shmid = shmget(k,SIZE,IPC_CREAT | IPC_EXCL|0666 );13     if(shmid==-1)14     {15         perror("shmger fail!!\n");16         exit(-1);17     }18 19     Log("create shm done",Debug)<<" sgmrevice shmid: "<<shmid<<endl;20 21 22     sleep(10);23     //挂接内存24     char*shmaddr=(char*)shmat(shmid,nullptr,0);25     if(*shmaddr==-1)26     {27         perror("shmat fail!\n");28     }29     Log("shmat shm seccese",Debug)<<" sgmrevice shmid: "<<shmid<<endl;30     sleep(10);31 32     //工作33 34     //拆除链接35     int n=shmdt(shmaddr);                                                                                                                                                                                                                                                                                                                                           36     assert(n!=-1);37     (void)n;38     Log("shmdt shm done",Debug)<<" sgmrevice shmid: "<<shmid<<endl;39 40     sleep(10);41     // n.删除共享内存42     n=shmctl(shmid,IPC_RMID,nullptr);43     assert(n!=-1);44     (void)n;45     Log("delete shm done",Debug)<<" sgmrevice shmid: "<<shmid<<endl;46 47     return 0;48 }
~

发送方代码

 1 #include"comm.hpp"                                                                                                                                                                                                               2 int main()3 {         4   //获取k值5   key_t k=ftok(PATH_NAME,PROJ_ID);6   assert(k!=-1);                  7   (void)k;                        8   Log("create key done  郑建云",Debug)<<"key:"<<TransToHex(k)<<endl;9   sleep(10);                                                        10   //创建共享内存                                                    11   //由于在receive已经创建共享内存,所以我们主要是找到内存挂接12   //IPC_CREAT==0                                             13   int shmid = shmget(k,SIZE,IPC_CREAT);                      14   if(!shmid)                           15   {                                    16     perror("shmget fail!!\n");17     exit(-1);                 18   }                           19              20   Log("create shm domw",Debug)<<" shmid: "<<shmid<<endl;21   int cnt=10;                                           22   while(cnt)                                            23   {          24     printf("time:%d\r",cnt--);25     sleep(1);                 26     fflush(stdout);           27   }                28   printf("\n");    29   //挂接,shmaddr,不要自己写,避免把其他数据覆盖30   char*shmaddr=(char*)shmat(shmid,nullptr,0);  31   if(shmaddr==nullptr)                         32   {                                          33     perror("shmat fail\n");34     exit(-1);              35   }                        36   Log("shmat sueecss done",Debug)<<"shmid: "<<shmid<<endl;37   sleep(10);                                              38                                                           39   //工作    40         41   //拆除共享内存                                                                                                            42   int n=shmdt(shmaddr);                                                                                                     43   printf("n=%d\n",n);                                                                                                       44   assert(n==0);                                                                                                             45   (void)n;                                                                                                                  46   Log("shmdt success done",Debug)<<" shmid "<<shmid<<endl;                                                                  47   printf("%p\n",shmaddr);                                                                                                   48   return 0;                                                                                                                 49 }                                          

执行顺序必须先执行接收代码,因为接收代码必须先创建好共享内存,然后发送方才可以链接。

否者,发送方先建立了,在执行中接收方将检查出内存中已经存在该key的共享内存,直接报错,返回一个-1到shmid。

相关文章:

systemV的工作原理+原理代码

概念 我们知道进程间的通信有管道的方式进程通信管道制作_云的小站的博客-CSDN博客 但是我们的管道通信其实属于一种取巧的方式&#xff0c;利用了打开的文件可读写的特性上&#xff0c;两个进程对此分别进行读写操作就会产生所谓的通信现象&#xff0c;但是外面的管道依旧得…...

Kubeflow--TFJob实现机制学习

2023暑期学习 TF Job实际场景应用Vertex AI TF Job 链接 https://www.kubeflow.org/docs/components/training/tftraining/ https://developer.aliyun.com/article/601779 TFJob实际上遵循Kubernetes标准的API定义. TFJob 对象 apiVersion --> string --> api版本&…...

百度出品,Nature重磅 -- 优化的mRNA设计算法可改善mRNA的稳定性和免疫原性

摘要 尽管mRNA疫苗已用于COVID-19的预防&#xff0c;但仍然面临不稳定和易降解的风险&#xff0c;这是mRNA疫苗存储、配送、效价等面临的重要障碍。先前的研究已表明&#xff0c;增加二级结构可延长mRNA的半衰期&#xff0c;再加上选择优化的密码子&#xff0c;可改善蛋白表达。…...

CKA 01_docker部署Kubernetes 部署docker 使用kubeadm引导集群 安装Pod网络

文章目录 1. 虚拟机步骤2. Docker 部署 Kubernetes2.1 部署 docker2.1.1 环境要求2.1.2 安装 docker 引擎2.1.3 worker 节点对 master 节点免密2.1.4 设定 docker 开机自启2.1.5 打开桥接&#xff0c;查看桥接流量2.1.6 设定 systemd 方式管理 cgroup2.1.7 docker部署完成2.1.8…...

Redis的使用规范小建议

Redis 核心技术与实战 笔记 作者&#xff1a; 蒋德钧 毕竟&#xff0c;高性能和节省内存&#xff0c;是我们的两个目标&#xff0c;只有规范地使用Redis&#xff0c;才能真正实现这两个目标。如果说之前的内容教会了你怎么用&#xff0c;那么今天的内容&#xff0c;就是帮助你用…...

操作受限的线性表——栈

本文主要内容&#xff1a;本文主要讲解栈的基本概念、基本操作和栈的顺序、链式实现。 目录 栈一、栈的基本概念1、基本概念2、基本操作 二、栈的顺序存储结构1、顺序栈的实现2、顺序栈的基本运算1&#xff09;初始化2&#xff09;判栈空3&#xff09;进栈4&#xff09;出栈5&a…...

C++基类指针或引用指向或引用派生类对象(实现动态多态四种手段)父类指针访问子类成员变量(需要dynamic_cast)

文章目录 背景多态示例&#xff1a;父类指针指向子类对象父类指针指向子类对象&#xff0c;如何通过父类指针访问到子类特定的成员变量实现动态多态的四种手段&#xff1a;基类的指针或引用指向或引用一个派生类对象&#xff08;new或不new&#xff09; 背景 比如有父类Animal…...

WTM框架运行报错0308010C:digital envelope routines::unsupported

WTM框架运行报错0308010C:digital envelope routines::unsupported 错误描述报错原因解决方式 错误描述 我所使用WTM搭建的程序是选择的.net5.0Vue前后端分离的方式&#xff0c;项目结构选择的是“各层分离的多个项目”&#xff1b;本人并非初次使用WTM平台框架搭建项目&#…...

(二)CSharp-索引器

1、索引器定义 什么是索引器 索引器&#xff08;indexer&#xff09;是这样一种成员&#xff1a;它使对象能够用与数组相同的方式&#xff08;即使用下标&#xff09;进行索引 索引器的声明参见 C# 语言定义文档注意&#xff1a;没有静态索引器 索引器是一组 get 和 set 访问…...

配合AI刷leetcode 实现1170

题目如下&#xff1a; 1170. 比较字符串最小字母出现频次 难度中等 75 定义一个函数 f(s)&#xff0c;统计 s 中&#xff08;按字典序比较&#xff09;最小字母的出现频次 &#xff0c;其中 s 是一个非空字符串。 例如&#xff0c;若 s "dcce"&#xff0c;那么…...

English Learning - L3 作业打卡 Lesson5 Day36 2023.6.9 周五

English Learning - L3 作业打卡 Lesson5 Day36 2023.6.9 周五 引言&#x1f349;句1: So next time you are on a train, look around and see what other people are reading, but dont jump to any conclusions.成分划分弱读连读爆破语调 &#x1f349;句2: You will probab…...

前端框架笔记

Vue.js的安装 安装Vue.js有两种方法&#xff1a; &#xff08;1&#xff09;类似于Bootstrap或jQuery&#xff0c;直接通过HTML文件中的标签引用。为了方便开发者使用&#xff0c;Vue.js提供了相关的CDN&#xff0c;通过如下代码可以引用最新版本的Vue.js&#xff1a; <sc…...

详细设计文档

1. 引言 1.1 目的 1.2 范围 1.3 定义、缩略语和缩写 1.4 参考文献 1.5 概述 2. 系统架构设计 2.1 总体架构 2.2 模块划分 2.3 数据流程设计 2.4 接口设计 3. 模块详细设计 3.1 登录模块详细设计 3.1.1 类设计 3.1.2 方法设计 3.1.3 数据库表设计 3.1.4 界面设计 3.2 文章管理模…...

Java011——Java数据类型转换(基本数据类型)

回顾&#xff1a;Java八大基本数据类型 大类 类型名称 关键字 占用内存 取值范围 --------------------------------------------------------------------------------------------|字节型 byte 1 字节 -128~127 整型 |短整型 short 2 字节 -32768~32…...

mybatis-plus用法(二)

(5条消息) mybatis-plus用法&#xff08;一&#xff09;_渣娃工程师的博客-CSDN博客 AR模式 ActiveRecord模式&#xff0c;通过操作实体对象&#xff0c;直接操作数据库表。与ORM有点类似。 示例如下 让实体类User继承自Model package com.example.mp.po; import com.bao…...

SQL笔记-存储过程+循环

存储过程循环使用方法 Oracle Oracle中存储过程的循环使用方法如下&#xff1a; DECLAREi NUMBER; BEGINi : 1;WHILE i < 10 LOOPDBMS_OUTPUT.PUT_LINE(i || i);i : i 1;END LOOP; END;其中&#xff0c;DECLARE用于声明变量&#xff0c;BEGIN和END用于标识存储过程的开始…...

HNU-操作系统OS-作业1(4-9章)

这份文件是OS_homework_1 by计科2102 wolf 202108010XXX 文档设置了目录,可以通过目录快速跳转至答案部分。 第四章 4.1用以下标志运行程序:./process-run.py -l 5:100,5:100。CPU 利用率(CPU 使用时间的百分比)应该是多少?为什么你知道这一点?利用 -c 标记查看你…...

springboot 精华

一、基础 官方文档地址&#xff1a;Spring Boot 注&#xff1a;以下部分例子 有些用到 .properties 方式&#xff0c;有些用 .yml方式&#xff0c;两者可自行学习&#xff0c;这里部分是为了省空间而写 .properties 方式。 1、泛谈 &#xff08;1&#xff09;优势 快速构建…...

我用ChatGPT写2023高考语文作文(三):新课标I卷

2023年 新课标I卷 适用地区&#xff1a;山东、福建、湖北、江苏、广东、湖南、河北、浙江 好的故事&#xff0c;可以帮我们更好地表达和沟通&#xff0c;可以触动心灵、启迪智慧&#xff1b;好的故事&#xff0c;可以改变一个人的命运&#xff0c;可以展现一个民族的形象……故…...

HTML 标签的学习

1.HTML 的结构 前端三剑客: HTML CSS JS,本章我们学习的是HTML HTML > 超文本标记语言 HTML代码是由"标签"构成的. 形如 <body>hello</body>标签名 (body) 放到 < > 中大部分标签成对出现. 为开始标签, 为结束标签.少数标签只有开始标签…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

探索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 数据…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...