windows下利用文件映射实现共享内存

2024-08-29 00:18

本文主要是介绍windows下利用文件映射实现共享内存,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

windows下利用文件映射实现共享内存的办法比较简单,下面是实现代码,细节用注释说明.
调用类似linux下shm的操作.该类没有进行太多的测试,欢迎提出问题和bug~~:)
#include <windows.h>
#include <string>
#include <iostream>
#include <assert.h>
using std::string;
using std::cout;
using std::endl;
#pragma warning(disable: 4311)class shareMemory
{
private:LPWSTR shm_name_u;bool  is_create_file;void * sh_base;HANDLE semaphore;HANDLE file_mapping;int  addr_len;
public:/*create_file用来说明是用磁盘文件映射还是页文件映射,如果用磁盘文件映射,共享内存不会出现存储器release后出现违规访问的问题,但是会在磁盘上建立一个文件,文件的名称由参数shm_name给定.如果用页文件映射,则不会在磁盘上建立一个文件*/shareMemory(const string& shm_name, bool create_file=false):is_create_file(create_file){   const char * _c_shm_name = shm_name.c_str();int _size =(int)shm_name.length()+1;shm_name_u=(LPWSTR)malloc(_size*2);MultiByteToWideChar(CP_ACP,0,_c_shm_name,_size,shm_name_u,_size);semaphore =  CreateSemaphore(NULL,1,1,NULL);sh_base = NULL;file_mapping = INVALID_HANDLE_VALUE;}void * shm_open(void* addr,const int length, DWORD protect){   addr_len = length; HANDLE _file_handle = INVALID_HANDLE_VALUE;if(is_create_file){_file_handle=CreateFile(shm_name_u,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
#ifdef _DEBUGif(_file_handle==INVALID_HANDLE_VALUE)cout<<"can not create file! we use page file instead!";
#endif  //end _DEBUG}/*打开指定名称的文件映射,如果不存在则创建一个*/file_mapping = OpenFileMapping(PAGE_READWRITE,false,shm_name_u );if(file_mapping!=NULL)goto file_mapping_exist;file_mapping = CreateFileMapping(_file_handle,NULL,PAGE_READWRITE,0,length,shm_name_u);
#ifdef _DEBUGassert(file_mapping);
#endif if(file_mapping==NULL)return NULL;
file_mapping_exist:sh_base = MapViewOfFileEx(file_mapping,protect,0,0,length,addr);CloseHandle(_file_handle);return sh_base;}/*往共享内存中写数据,返回写出数据的字节个数*/int  shm_write(void *dest, void * src, int size){   if(!check_adress(dest))return -1;int _write_count = (int)sh_base+addr_len - (int)dest;if(_write_count>size)_write_count = size;
/*利用semaphore进行保护映射的区域(同一进程的不同线程调用时候才进行保护)*/WaitForSingleObject(semaphore,INFINITE);memcpy(dest,src,_write_count); ReleaseSemaphore(semaphore,1,NULL);FlushViewOfFile(sh_base,_write_count);return _write_count;}/*从共享内存中读数据,返回读出的数据字节个数**/
int  shm_read(void* src, void * dest, int size){if(!check_adress(src))return -1;int _read_count = (int)sh_base+addr_len -(int) src;if(_read_count>size)_read_count = size;memcpy(dest,src,_read_count);return _read_count;}~shareMemory(){ UnmapViewOfFile(sh_base);free(shm_name_u);CloseHandle(semaphore);CloseHandle(file_mapping);}private :
/*进行地址检测*/bool check_adress(void* addr){if( ( (int)addr <(int)sh_base) || ((int)addr > (int)sh_base+addr_len) ){SetLastError(ERROR_ACCESS_DENIED);
#ifdef _DEBUGprintf("access denied,the destination address out of the map view!");
#endif //_DEBUGreturn  false;}return true;}
};

测试:
写进程的主函数:

int main()
{shareMemory sm("boost", false);void * bs = sm.shm_open(NULL,1000*4,FILE_MAP_WRITE);if(bs==NULL)return -1;int a[10];for(int i=0; i<10; ++i)a[i] = i;sm.shm_write(bs,a,10*4);Sleep(100000);
}
读进程的主函数:

int main()
{shareMemory sm("boost", false);void * bs = sm.shm_open(NULL,1000,FILE_MAP_READ);if(bs==NULL){   cout<<"null";return -1;}int b[10];sm.shm_read(bs,b,10*4);for(int i=0; i<10; ++i)cout<<b[i]<<"  ";
}

/另一个例子//

http://blog.csdn.net/zhao_fu_lu/article/details/41730699


这篇关于windows下利用文件映射实现共享内存的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1116299

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注

通过React实现页面的无限滚动效果

《通过React实现页面的无限滚动效果》今天我们来聊聊无限滚动这个现代Web开发中不可或缺的技术,无论你是刷微博、逛知乎还是看脚本,无限滚动都已经渗透到我们日常的浏览体验中,那么,如何优雅地实现它呢?... 目录1. 早期的解决方案2. 交叉观察者:IntersectionObserver2.1 Inter