欢迎登陆真网站,您的到来是我们的荣幸。 登陆 注册 忘记密码? ☆设为首页 △加入收藏
欢迎加入真幸福QQ群
电脑知识: 基础知识 网络技术 操作系统 办公软件 电脑维修 电脑安全 windows7 windows8 windows10 服务器教程 平板电脑 视频播放教程 网络应用 互联网 工具软件 浏览器教程 QQ技巧 输入法教程 影视制作 YY教程 wps教程 word教程 Excel教程 PowerPoint
云南西双版纳特产小花糯玉米真空包装


linux中mysql开机自动启动3种方法
思科交换机配置命令
思科路由器配置命令教程
如何让迅雷支持更多浏览器
如何卸载一键还原精灵
服务器安全狗清理注册表教程
配置Nginx子域名泛解析绑定至单独目录
服务器安全狗怎么设置黑白名单
不一样的WIN2003服务器安全配置技巧
Windows命令行下编译包含中文字符的Java文件报错
windows下利用文件映射实现共享内存
【 来源:网络 】【 点击:2 】 【 发布时间:2017_03_03 08:59:59 】

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 _DEBUG  if(_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 _DEBUG   assert(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 _DEBUG   printf("access denied,the destination address out of the map view!");#endif //_DEBUG   return  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]<<"  ";}


本网站由川南居提供技术支持,fkzxf版权所有 浙ICP备12031891号
淳安分站 淳安分站