2.3 主程序和外部IO交互 (文件映射方式)----IO Server实现

2.3 主程序和外部IO交互 (文件映射方式)----IO Server C++实现

效果显示

在这里插入图片描述

1 内存共享概念

基本原理:以页面为单位,将一个普通文件映射到内存中,达到共享内存和节约内存的目的,通常在需要对文件进行频繁读写时使用,这样用内存读写取代I/O读写,以获得较高的性能
windows和linux都提供了原生的系统级的C++接口,可以将文件映射到内存

优点: 32位|64位 客户端都可以同时连接到Server上

1 参考资料 探索内存原理的内存映射文件(图文详解)

2 IO交互工作示意图

1 必须先打开IO Server 创建内存映射,然后打开IO Client才有效
2 IO Client 可以32位也可以64位
IO 交互示意图

3 C++ 代码实现

3.1 shareddataServer.h 头文件中引用

尽量做到Windows |Linux 下都能够通用

 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)#define WIN32_LEAN_AND_MEAN             //  从 Windows 头文件中排除极少使用的信息#include <windows.h>
#elif defined(linux) || defined(__linux)#include <string.h>#include <sys/mman.h>#include <fcntl.h>#include <unistd.h> 
#endif 
3.2 shareddataServer.h 主要调用接口

在后面的测试中,我们主要演示DM8 来作为IO的 输入和输出

3.2.1 预定义变量名称,为了能够Linux|Windows下通用
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)   #elif defined(linux) || defined(__linux)typedef void *HANDLE;typedef void *LPVOID;typedef long long __int64;typedef __int64 LONG_PTR, *PLONG_PTR;typedef unsigned long long ULONG_PTR;typedef unsigned long long  *PULONG_PTR; typedef int BOOL; #define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
#endif
3.2.2 接口定义

BD_API  int  GetIOData(uchar* p_IOData, int start, int len);
BD_API  int  SetIOData(uchar* p_IOData, int start, int len);
BD_API  int  SetDM8(uchar* p_DM8, int start, int len);
BD_API  int  GetDM8(uchar* p_DM8, int start, int len);
BD_API  int  GetDM16(uchar* p_DM16, int start, int len);
BD_API  int  SetDM16(uchar* p_DM16, int start, int len); /*** ************************************************************************************************ @brief ReleaseMMF* 销毁资源* * @return BD_API * ************************************************************************************************/
BD_API void ReleaseMMF();
/*** ************************************************************************************************ @brief * * * @return BD_API * ************************************************************************************************/
BD_API int Create_Server();
3.3 shareddataServer.cpp 接口实现
3.3.0 MMF 句柄定义
namespace SHAREDDATA
{ #pragma region MMF 内存共享 IO 区// 创建共享文件句柄 HANDLE hMapFile_IO = INVALID_HANDLE_VALUE;// 文档句柄int  fd_io=-1;#pragma endregion MMF 内存IO 区#pragma region MMF 内存共享 DM8 区// 创建共享文件句柄 HANDLE hMapFile_DM8 = INVALID_HANDLE_VALUE;// 文档句柄int  fd_dm8=-1;#pragma endregion MMF 内存DM8 区#pragma region MMF 内存共享 DM16 区// 创建共享文件句柄 HANDLE hMapFile_DM16 = INVALID_HANDLE_VALUE;// 文档句柄int  fd_dm16=-1;#pragma endregion MMF 内存DM16 区
} 
3.3.1 Create_Server()
namespace SHAREDDATA
{ 
/*** ************************************************************************************************ @brief * Create_Server* 创建一个server* * @return BD_API * ************************************************************************************************/BD_API int  Create_Server()
{int nRet = 0; try{ 	#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)// &0 DMIOhMapFile_IO = CreateFileMapping(INVALID_HANDLE_VALUE,   // 物理文件句柄NULL,   // 默认安全级别PAGE_READWRITE,   // 可读可写0,   // 高位文件大小n_max_IO_uchars,   // 低位文件大小"ShareMemoryIO"   // 共享内存名称);if (hMapFile_IO != INVALID_HANDLE_VALUE&&   hMapFile_IO > 0)nRet = 0;else return   -1;// &1 DM8hMapFile_DM8 = CreateFileMapping(INVALID_HANDLE_VALUE,   // 物理文件句柄NULL,   // 默认安全级别PAGE_READWRITE,   // 可读可写0,   // 高位文件大小n_max_DM8s,   // 低位文件大小"ShareMemoryDM8"   // 共享内存名称  );if (hMapFile_DM8 != INVALID_HANDLE_VALUE && hMapFile_DM8 > 0)nRet = 0;else return   -1;// &2 DM16hMapFile_DM16 = CreateFileMapping(INVALID_HANDLE_VALUE,   // 物理文件句柄NULL,   // 默认安全级别PAGE_READWRITE,   // 可读可写0,   // 高位文件大小n_max_DM16s,   // 低位文件大小"ShareMemoryDM16"   // 共享内存名称); #elif defined(linux) || defined(__linux)// specify shared file path// 路径一定要存在,否则会报警// &0 DMIOstring  shared_file_io = path+"ShareMemoryIO";fd_io = open(shared_file_io.c_str(), O_CREAT | O_RDWR | O_TRUNC, 00777);if (fd_io < 0){cout << "create file error" << endl;return -1;}ftruncate(fd_io, n_max_IO_uchars); // extend file size// map memory to file//hMapFile_IO = mmap(NULL, 			n_max_IO_uchars,    , PROT_READ | PROT_WRITE, MAP_SHARED, fd_io, 0);     // &0 DM8string shared_file_dm8 = path+"ShareMemoryDM8";fd_dm8 = open(shared_file_dm8.c_str(), O_CREAT | O_RDWR | O_TRUNC, 00777);if (fd_dm8 < 0){cout << "create file error" << endl;return -1;}ftruncate(fd_dm8, n_max_DM8s); // extend file size// map memory to file//hMapFile_DM8 = mmap(NULL, n_max_DM8s,    , PROT_READ | PROT_WRITE, MAP_SHARED, fd_dm8, 0);// &0 DM16string shared_file_dm16= path+"ShareMemoryDM16";fd_dm16 = open(shared_file_dm8.c_str(), O_CREAT | O_RDWR | O_TRUNC, 00777);if (fd_dm16 < 0){cout << "create file error" << endl;return -1;}ftruncate(fd_dm16, n_max_DM16s); // extend file size  #endif}catch (exception& e){nRet = -1;}return nRet;
}
#pragma region  销毁共享文件 句柄
// 销毁内存 MMF 句柄
BD_API void ReleaseMMF()
{
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)  if (hMapFile_IO != NULL)CloseHandle(hMapFile_IO);if (hMapFile_DM8 != NULL)CloseHandle(hMapFile_DM8);if (hMapFile_DM16 != NULL)CloseHandle(hMapFile_DM16); 
#elif defined(linux) || defined(__linux)if(fd_io>=0)close(fd_io);if(fd_dm8>=0)close(fd_dm8);if(fd_dm16>=0)close(fd_dm16);#endif
} 
#pragma endregion  
}
3.3.2 重新定义MapViewofFile_New| UnMapViewofFile_New
 LPVOID  MapViewofFile_New(HANDLE handle,const int& fd, const int& size) {LPVOID lpBase=nullptr;if(handle==nullptr||size==0)return lpBase;#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)   // 映射缓存区视图 , 得到指向共享内存的指针lpBase = MapViewOfFile(handle,            // 共享内存的句柄FILE_MAP_ALL_ACCESS, // 可读写许可0,0,size);#elif defined(linux) || defined(__linux)if(fd<0)return nullptr;// map memory to filelpBase = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);#endifreturn lpBase;}void  UnMapViewofFile_New(HANDLE handle,const int& size){if(handle==nullptr||size==0)return ;#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)   // 解除文件映射UnmapViewOfFile(handle);#elif defined(linux) || defined(__linux)// unmap and closemunmap(handle, size);#endifreturn;}
3.3.3 SetDM8|GetDM8 函数接口实现
   /// @brief SetDM8/// @param p_DM8 /// @param start /// @param len /// @return BD_API  int  SetDM8(uchar* p_DM8, int start, int len){int nRet = 0;std::lock_guard<std::mutex> lock(_mutex);try{if (start > n_max_DM8s){len = 0;nRet = -1;return nRet;}if (len + start > n_max_DM8s){len = n_max_DM8s - start;}//  len 一定》0if (len > 0){          // 映射缓存区视图 , 得到指向共享内存的指针LPVOID lpBase = MapViewofFile_New(hMapFile_DM8,fd_dm8,  n_max_DM8s);  memcpy((uchar*)lpBase + start, p_DM8, len);//memcpy(DM_8 + start, p_DM8, len);// 解除文件映射  UnMapViewofFile_New(lpBase, n_max_DM8s);}else nRet = -1;}catch (exception& e){nRet = -1;}return nRet;}BD_API  int  GetDM8(uchar* p_DM8, int start, int len){int nRet = 0;std::lock_guard<std::mutex> lock(_mutex);try{if (start > n_max_DM8s){nRet = -1;return nRet;}if (len + start > n_max_DM8s){len = n_max_DM8s - start;}//  len 一定》0if (len > 0){if (hMapFile_DM8 == INVALID_HANDLE_VALUE)return -2;// 映射缓存区视图 , 得到指向共享内存的指针LPVOID lpBase = MapViewofFile_New(hMapFile_DM8,fd_dm8,  n_max_DM8s);                  // copy 内存memcpy(p_DM8, (uchar*)lpBase + start, len);//memcpy(p_DM8, DM_8 + start, len);// 解除文件映射UnMapViewofFile_New(lpBase, n_max_DM8s);                }else nRet = -1;}catch (exception& e){nRet = -1;}return nRet;}

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

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

相关文章

手写一个类似@RequestParam的注解(用来接收请求体的参数)

一、本文解决的痛点 按照大众认为的开发规范&#xff0c;一般post类型的请求参数应该传在请求body里面。但是我们有些post接口只需要传入一个字段&#xff0c;我们接受这种参数就得像下面这样单独创建一个类&#xff0c;类中再添加要传入的基本类型字段&#xff0c;配合Reques…

LLM指令微调Prompt的最佳实践(二):Prompt迭代优化

文章目录 1. 前言2. Prompt定义3. 迭代优化——以产品说明书举例3.1 产品说明书3.2 初始Prompt3.3 优化1: 添加长度限制3.4 优化2: 细节纠错3.5 优化3: 添加表格 4. 总结5. 参考 1. 前言 前情提要&#xff1a; 《LLM指令微调Prompt的最佳实践&#xff08;一&#xff09;&#…

nexus未开启匿名访问Anonymous Access,访问maven元数据maven-metadata,报401未授权Unauthorized错误

一、背景 下午在调试nexus的时候&#xff0c;其他同事不小心把匿名访问停用了&#xff0c;导致客户端android打包的时候&#xff0c;报错&#xff1a; Received status code 401 from server: Unauthorized。 访问http://192.168.xx.xx:8081/repository/public/com/xxx/xxxcor…

【软件测试】单元测试、系统测试、集成测试详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、单元测试的概念 单元测试是对软件基本组成单元进行的测试&#xff0c;如函数或一个类的方法…

PCL 点云最小图割(前景、背景点云提取)

点云最小图割 一、概述1.1 概念1.2 算法原理二、代码示例三、运行结果🙋 结果预览 一、概述 1.1 概念 最小图割算法(pcl::MinCutSegmentation):是一种基于图论的对象分割方法,主要用于点云数据的处理和分析。该算法将点云数据表示为一个图结构,其中点云中的点作为图的节…

【Java】微博系统设计:怎么应对热点事件的突发访问压力?

一、问题解析 微博&#xff08;microblog&#xff09;是一种允许用户即时更新简短文本&#xff08;比如140个字符&#xff09;&#xff0c;并可以公开发布的微型博客形式。今天我们就来开发一个面向全球用户、可以支持10亿级用户体量的微博系统&#xff0c;系统名称为“Weitte…

不同系统间数据交换要通过 api 不能直接数据库访问

很多大数据开发提供数据给外部系统直接给表结构&#xff0c;这是不好的方式。在不同系统间进行数据交换时&#xff0c;通过API&#xff08;应用程序编程接口&#xff09;而非直接访问数据库是现代系统集成的一种最佳实践。 目录 为什么要通过API进行数据交换如何通过API进行数据…

UG NX二次开发(C#)-根据草图创建拉伸特征(UFun+NXOpen)

文章目录 1、前言2、在UG NX中创建草图,然后创建拉伸特征3、基于UFun函数的实现4、基于NXOpen的实现代码1、前言 UG NX是基于特征的三维建模软件,其中拉伸特征是一个很重要的特征,有读者问如何根据草图创建拉伸特征,我在这篇博客中讲述一下草图创建拉伸特征的UG NX二次开发…

分布式链路追踪Micrometer Tracing和ZipKin基础入门与实践

【1】概述 在分布式与微服务场景下&#xff0c;我们需要解决如下问题&#xff1a; 在大规模分布式与微服务集群下&#xff0c;如何实时观测系统的整体调用链路情况。 在大规模分布式与微服务集群下&#xff0c;如何快速发现并定位到问题。 在大规模分布式与微服务集群下&…

AI网络爬虫006:从当当网批量获取图书信息

文章目录 一、目标二、输入内容三、输出内容一、目标 用户输入一个图书名称,然后程序自动从当当网批量获取图书信息 查看相关元素在源代码中的位置: 二、输入内容 第一步:在deepseek中输入提示词: 你是一个Python爬虫专家,一步步的思考,完成以下网页爬取的Python脚本任…

法制史学习笔记(个人向) Part.3

5. 三国两晋南北朝法律制度 以下为三国魏晋南北朝直到唐代的历史发展脉络图&#xff1a; #mermaid-svg-6AVVMjllKTBaBbRO {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-6AVVMjllKTBaBbRO .error-icon{fill:#55222…

【Python实战因果推断】14_线性回归的不合理效果4

目录 Debiasing Step Denoising Step Standard Error of the Regression Estimator Debiasing Step 回想一下&#xff0c;最初由于混杂偏差&#xff0c;您的数据看起来是这样的、 随着信贷额度的增加&#xff0c;违约率呈下降趋势&#xff1a; 根据 FWL 定理&#xff0c;您可…

c文件读写

格式输入输出 文件指针 FILE *pf 文件打开 fopen("文件名",打开方式)  文件名&#xff1a;普通字符串 打开方式&#xff1a;读、写、文本文件、二进制文件 rt、wt、at、rb、wb、ab、rt、wt、at、rb、wb、ab (r 为读&#xff0c;w 为写&#xff0c; 为读写&…

解锁机器学习潜力的钥匙:深度剖析交叉验证集的应用与魅力

一、为何需要交叉验证集 在构建机器学习模型时&#xff0c;我们通常会面临一个关键问题&#xff1a;如何确保模型在新数据上的表现与在训练数据上一样出色&#xff1f;这涉及到模型的泛化能力——即模型对未见过的数据做出准确预测的能力。传统的训练集/测试集划分方法虽然简单…

亿纬锂能社招入职通用职业能力测评大易题库及薪资待遇

一、亿纬锂能薪资待遇 1. **平均工资**&#xff1a;根据职朋职业圈的数据&#xff0c;惠州亿纬锂能股份有限公司的平均工资为10924元/月。网易新闻的报道则提到&#xff0c;亿纬锂能的月收入平均值为16598元。 2. **工资区间**&#xff1a;在亿纬锂能&#xff0c;工资收入有多…

使用dot来画流程图

Dot是一种图形描述语言&#xff0c;属于Graphviz软件的一部分。Graphviz是一个用于可视化图形&#xff08;图表、网络图等&#xff09;的开源工具集。使用Dot语言&#xff0c;你可以创建并描述节点和边&#xff0c;从而生成图形。以下是如何使用Dot语言画图的基本步骤&#xff…

【CSAPP】-attacklab实验

目录 实验目的与要求 实验原理与内容 实验设备与软件环境 实验过程与结果&#xff08;可贴图&#xff09; 实验总结 实验目的与要求 1. 强化机器级表示、汇编语言、调试器和逆向工程等方面基础知识&#xff0c;并结合栈帧工作原理实现简单的栈溢出攻击&#xff0c;掌握其基…

游游的水果大礼包(枚举)

题目链接&#xff1a;https://ac.nowcoder.com/acm/problem/255193 题解 题目解析 就拿第一个例子来看&#xff0c;当选择组成1个一号礼包和1个二号礼包时最大的价值是3元&#xff0c;而选择2个二号礼包时&#xff0c;最大的价值是4元&#xff0c;因此选择2个二号礼包。 算法…

2-23 基于matlab的小波变换碰磨故障信号的特征提取

基于matlab的小波变换碰磨故障信号的特征提取&#xff0c;可以画出信号原图&#xff0c;轴心轨迹&#xff0c;频谱图以及多层小波变换的重构信号。程序已调通&#xff0c;可直接运行。 2-23 小波变换 碰磨故障信号 轴心轨迹 - 小红书 (xiaohongshu.com)

html+css+js写的多人在线积分系统

可以添加成员&#xff0c;成员名称自定义 可以对各个成员加分减分➕➖ 可以删除成员 源码在图片下面&#xff0c;记得点赞加关注❤️❤️❤️ 界面 源代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8">…