一.CreateFileMapping实现的共享内存及用法

news2024/11/27 4:12:21

共享内存概念

1.在32位的Windows系统中,每一个进程都有权访问他自己的4GB(232=4294967296)平面地址空间,没有段,没有选择符,没有near和far指针,没有near和far函数调用,也没有内存模式。

2.每个进程都有独立的4GB逻辑地址空间,32位的Windows系统允许每一个进程独立访问自己的内存,即独立于其它进程,也即它自己的32位逻辑地址空间。操作系统将把每一个进程的逻辑地址转换成实际的物理地址,独立的地址空间可以使其他已经出错的进程之间相互隔离,入阁一个进程通过他自己的内存空间处理数据,其他的进程就比在DOS中安全,在DOS中的所有应用程序共享相同的物理内存空间,虽然这带来了许多好处,但在不同进程之间转的指针,就会出现一些麻烦。在一个进程中,一个给定的逻辑地址将与另一进程的指针不会有相同的逻辑地址。

3.那么怎么样才能在32位的Windows系统中达到共享内存的目的呢?

4.随着进程的分离内存空间的出现,进程不能简单地使用GlobalAlloc()函数来分配内存,并把它转递给另一个进程来共享,一个进程检查有另一个进程分配的指针,他只是指向随机地址。然而,在32位的Windows系统支持在进程间共享内存映象文件,可以通过内存映象文件来达到内存共享的目的。

5.32位的Windows系统的虚拟内存系统具有把实际内存映象到页面文件或交换文件的能力.通过把内存映象到任何想映象的文件,包括系统页面本身,应用程序就可以拓展这种能力。文件影响能用来提供更快更简捷的文件访问方式,并提供内存共享。

6.然后把文件映像到内存,首先必须调用CreateFileMapping()函数,然后再调用MapViewOfFile函数,把文件视映像到进程地址空间上。

使用方法

1.要把文件映像到内存,首先必须调用CreateFileMapping()函数,它需要用一个由CreateFile()函数打开并返回的文件句柄,对大多数共享内存应用程序。必须把此句柄设置为0xFFFFFFFF,用来指定系统页面文件。通过使用上面的特殊句柄,可以不调用CreateFile函数,当然在完成时,也不必有一个内存的磁盘文件拷贝。

2.CreateFileMapping()函数的第二个参数是一个指向SECURITY_ATTRIBUTES结构的指针,它指明返回的句柄是否可以被子进程所继承。另外,在SECURITY_ATTRIBUTES结构中,也包括一个安全性描述的子指针,它由WinNT支持它的安全机制。

3.第三个参数允许指定内存块的访问权限,权限值有PAGE_READONLY、PAGE_READWRITE和PAGE_WRITECOPY,PAGE_WRITECOPY可以在指定页面上拷贝并写访问。这意味着当一个进程映像此内存并写入时,它将得到自己修改数据的拷贝,面不是写到共享内存空间,另外,可以把几个标志一起使用来指定其他部分的属性。

4.其他参数允许指定内存块的最大尺寸,如果内存块的尺寸比第一个 参数中指定的文件尺寸还要大,这个文件就增大。

5.最后一个参数为内存映像对象指定名字,通过调用CreateFileMapping函数和OpenFileMapping函数,其他进程可用这个名字来访问相同的文件映像。

6.一旦一个内存映像对象由CreateFileMapping()创建成功,可以调用MapViewOfFile函数把文件视映像到进程地址空间上,这个函数需要用一个由CreateFileMapping()函数或OpenFileMapping()函数返回的句柄,并允许指定访问模式和映像的字节数,以及文件映像对象中的偏移量。另外,还可以使用MapViewOfFileEx()函数来实现同样的功能,只是此函数还允许指定映像对象的起始地址。

7.当用完映像文件后,可以通过调用UnmapViewOfFile函数,释放映像内存并把一些映像数据写入文件(除非它是交换文件),如果想立即把数据写回磁盘文件,那就需要调用FlushViewOfFile()函数把映像内存写入文件。

8.为了便于读者对以上程序的理解和进行下一步的学习,这里再简单介绍一下Win32内存模式。在开始学习Win32内存管理之前,最好先了解一些16位Windows与32位Windows的区别,它们之间的主要区别是把寄存器和指针长度变为32位。

9.Win32 API允许应用程序访问虚拟内存,如果想保存大量的数据,这十分有用,尽管大部分空间从来没有用于物理存储。虚拟内存页有四种状态,提交页面被分配一个物理存储单元,不管它是在是在交换文件中,提交页面被锁定后就强行留在内存中,直到解锁为止。保留页面存储一块保留地址国,它不被分配任何存储单元,自由页面都没有用。

10.VirtualAlloc()函数可用来分配从指定逻辑内存开始的一定范围内的地址,该函数的另一个参数允许指定访问保护标志,并指定内存是否被保存或被用于物理存储单元,也可以调用此函数来调配前面保存的虚拟内存页。

11.可以通过调用GloballLock()函数来强制使内存块留在物理内存中,应该谨慎使用此函数,因为它阻止系统管理这块内存,直到调用GlobalUnlock()函数为止。如果一个进程锁定了一大块内存,其他进程就会终止,不管还有多少内存。

12.函数VirtualProtect()用于改变一块内存的访问权限,VirtualQuery()函数返回内存页的住处。如果想访问其他进程的页面,可以通过调用VirtualProtecteEx和VirutalQueryEx两个函数来实现。

函数解析

1.CreateFileMapping

HANDLE CreateFileMapping(
HANDLE hFile,                       //物理文件句柄
LPSECURITY_ATTRIBUTES lpAttributes, //安全设置
DWORD flProtect,                      //保护设置
DWORD dwMaximumSizeHigh,                      //高位文件大小
DWORD dwMaximumSizeLow,                      //低位文件大小
LPCTSTR lpName                      //共享内存名称
);
hFile是创建共享文件的句柄。
lpFileMappingAttributes是文件共享的属性。
flProtect是当文件映射时读写文件的属性。
dwMaximumSizeHigh是文件共享的大小高位字节。
dwMaximumSizeLow是文件共享的大小低位字节。
lpName是共享文件对象名称。
hFileMappingObject是共享文件对象。
dwDesiredAccess是文件共享属性。
dwFileOffsetHigh是文件共享区的偏移地址。
dwFileOffsetLow是文件共享区的偏移地址。
dwNumberOfBytesToMap是共享数据长度。

2.主要前3个参数说明

2.1.物理文件句柄任何可以获得的物理文件句柄, 如果你需要创建一个物理文件无关的内存映射也无妨, 将它设置成为 0xFFFFFFFF(INVALID_HANDLE_VALUE)就可以了.

2.2.如果需要和物理文件关联, 要确保你的物理文件创建的时候的访问模式和"保护设置"匹配, 比如: 物理文件只读, 内存映射需要读写就会发生错误. 推荐你的物理文件使用独占方式创建.

2.3.如果使用 INVALID_HANDLE_VALUE, 也需要设置需要申请的内存空间的大小, 无论物理文件句柄参数是否有效, 这样 CreateFileMapping 就可以创建一个和物理文件大小无关的内存空间给你, 甚至超过实际文件大小, 如果你的物理文件有效, 而大小参数为0, 则返回给你的是一个和物理文件大小一样的内存空间地址范围. 返回给你的文件映射地址空间是可以通过复制, 集成或者命名得到, 初始内容为0.

2.4.保护设置就是安全设置, 不过一般设置NULL就可以了, 使用默认的安全配置. 在win2k下如果需要进行限制, 这是针对那些将内存文件映射共享给整个网络上面的应用进程使用是, 可以考虑进行限制.

综合应用场景

1.在开发软件过程里,也经常碰到进程间共享数据的需求。比如A进程创建计算数据,B进程进行显示数据的图形。

2.这样的开发方式可以把一个大程序分开成独立的小程序,提高软件的成功率,也可以更加适合团队一起开发,加快软件的开发速度。下面就来使用文件映射的方式进行共享数据。

3.先要使用函数CreateFileMapping来创建一个想共享的文件数据句柄,然后使用MapViewOfFile来获取共享的内存地址,

4.然后使用OpenFileMapping函数在另一个进程里打开共享文件的名称,这样就可以实现不同的进程共享数据。

void FileMapping(void)
{
	 //打开共享的文件对象。
	 m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,_T("didaxueyuan"));
	 if (m_hMapFile)
	 {
		   //显示共享的文件数据。
		   LPTSTR lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS,,,);
		   OutputDebugString(lpMapAddr);
	 }
	 else
	 {
		   //创建共享文件。
		   m_hMapFile = CreateFileMapping( (HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,,,_T("TestFileMap"));

		   //拷贝数据到共享文件里。
		   LPTSTR lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS,,,);
		   std::wstring strTest(_T("TestFileMap"));
		   wcscpy(lpMapAddr,strTest.c_str());

		   FlushViewOfFile(lpMapAddr,strTest.length()+);
	 }
}

解析说明代码例子

1.与虚拟内存类似,保护方式可以是PAGE_READONLY或是PAGE_READWRITE。如果多进程都对同一共享内存进行写访问,则必须保持相互间同步。映射文件还可以指定PAGE_WRITECOPY标志,可以保证其原始数据不会遭到破坏,同时允许其他进程在必要时自由的操作数据的拷贝。

2.在创建文件映射对象后使用可以调用MapViewOfFile函数映射到本进程的地址空间内。

3.下面说明创建一个名为MySharedMem的长度为4096字节的有名映射文件:

HANDLE hMySharedMapFile=CreateFileMapping((HANDLE)0xFFFFFFFF),NULL,PAGE_READWRITE,0,0x1000,"MySharedMem");

4.并映射缓存区视图:

LPSTR pszMySharedMapView=(LPSTR)MapViewOfFile(hMySharedMapFile,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);

5.其他进程访问共享对象,需要获得对象名并调用OpenFileMapping函数。

HANDLE hMySharedMapFile=OpenFileMapping(FILE_MAP_WRITE,FALSE,"MySharedMem");

6.一旦其他进程获得映射对象的句柄,可以象创建进程那样调用MapViewOfFile函数来映射对象视图。用户可以使用该对象视图来进行数据读写操作,以达到数据通讯的目的。

7.当用户进程结束使用共享内存后,调用UnmapViewOfFile函数以取消其地址空间内的视图:

if (!UnmapViewOfFile(pszMySharedMapView))
{
  MessageBox("卸载映射地址失败");
}

8.好了,今天的一章节就讲到这里,感谢大家的支持285530835

B0220.jpg

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

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

相关文章

CUDA并行编程

gpu 图形处理专用单元 cpu是主机单元 gpu显卡处理器 专门执行复杂数学和几何计算 不同表面有不同光纤效果 必须达到快速计算能力 gpu专门设计为大规模并行吞吐处理设计 用于加速图形显示 , 吞吐量高 峰值计算能力 4612 GFLOP/S 一秒钟可以计算4612G次浮点数计算…

SQL注入实操

文章目录 一、sqli-lab靶场搭建二、通关笔记1.Less-1a.单引号‘b.updatexmlc.concatd.unione.information_schemaf.GROUP_CONCATg.select 1,2 2.Less-2 一、sqli-lab靶场搭建 下载路径:https://www.hibugs.net/hi-resource/sqli-labs-master.zip 下载后解压复制到w…

腾讯数据中台项目集管理实战分享︱腾讯高级项目经理张嵎桐

腾讯PCG大数据平台部高级项目经理张嵎桐先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾,演讲议题:腾讯数据中台项目集管理实战分享。大会将于8月12-13日在北京举办,敬请关注! 议题简要: 在“IT时代”向“…

9、加载cesium世界地形

本节演示使用CCsium库加载cesium的世界地形,使用第四节单击事件的例子,修改点击事件添加地形。 1、ceisum显示地形需要引入CesiumTerrainProvider和CreateWorldTerrain类。与ceisum类似,修改鼠标点击事件,创建地形并添加到ceisum…

Apache Doris (二十八):Doris 数据导入(六)Spark Load 1- 原理及配置

目录 1. 基本原理 2. Spark集群搭建 2.1 Spark Standalone 集群搭建 2.2 Spark On Yarn 配置 3. Doris配置Spark与Yarn 3.1 Doris配置Spark 3.2 Doris配置Yarn 进入正文之前,欢迎订阅专题、对博文点赞、评论、收藏,关注IT贫道,获取高质…

leetcode:定长字串中元音的最大数目

定长字串中元音的最大数目 medium 给你字符串 s 和整数 k 。 请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。 英文中的 元音字母 为(a, e, i, o, u)。 示例 1: 输入:s "abciiidef", k 3 输出…

KBLAutoSwitch偶尔无法自动切换输入法的问题

KBLAutoSwitch(https://github.com/flyinclouds/KBLAutoSwitch)是一款中英文输入法自动切换软件,但是在使用过程中偶尔会出现无法自动切换成自己想要的输入法的问题,比如我将cmd窗口设为自动切换英文输入法,但是在使用…

计算机组成原理 期末复习

在我的博客查看:https://chenhaotian.top/study/computer-composition-principles-final-review/ 如果遇到 外链图片转存失败 ,直接打开链接查看图片 计算机组成原理 期末复习 第 1 章 计算机系统概论 1.1 计算机的诞生和发展 冯诺依曼体系 1.2 计算…

LLaMA以及其扩展模型总结(一)

自从ChatGPT发布以来,人们看到了AGI时代的曙光,但是由于ChatGPT是闭源的,只能在官网体验和使用API进行访问,据OpenAI CEO说是出于AGI的安全性考虑,这样大大限制了很多研究人员和机构对于AGI的研究进展。Meta公司反其道…

在线转换视频格式到mp4怎么换?分享两个方法!

在日常生活和工作中,我们常常需要将视频文件转换为MP4格式以便于在各种设备上播放和共享。本文将介绍两种快速转换视频格式为MP4的方法,一种是使用记灵在线工具,另一种是使用一个在线转换工具。 方法一:记灵在线工具 记灵是一款…

LED驱动(原始架构)——STM32MP157

文章目录 硬件知识 LED 原理GPIO 引脚操作方法GPIO 模块一般结构GPIO 寄存器的一般操作 STM32MP157的GPIO操作方法先使能PLL4MPU、MCU共享GPIO模块1. 在MPU上使能某个GPIO模块2. 在MCU上使能某个GPIO模块 GPIO模块设置引脚工作模式:GPIO模式对于输出引脚&#xff1a…

模块化+命名空间

1.目的:为了让代码更好维护,让多种数据分类更加明确 2.修改src/store/index.js为了解决不同模块命名冲突的问题,将不同模块的namespaced:true,之后在不同页面中引入getter actions mutations state,需要加上所属的模块…

ADC基础进阶

ADC 啊.... 拿华大的来举例吧... 最少要知道了两个电路。 1. VERF 华大HC32F60的ADC以VREF为内部基准电压,如果VREFH管教悬空,那么实际其基准电压应该是MCU_3.3V,如果VREFH额外搭电路提供电压,应该是以其实际提供的电压为准&am…

Uber是如何解决数据一致性问题的呢?

Uber的请求流程非常复杂,如上图所示,他们使用Spanner来存储大量数据。Spanner是一个全面托管的、关键的关系型数据库服务,可以在全球范围内提供事务一致性和高可用性的自动同步复制。 但是,当扩展到数百万并发请求时,使…

【2023 年第二届钉钉杯大学生大数据挑战赛】 初赛 B:美国纽约公共自行车使用量预测分析 问题一Python代码分析

2023 年第二届钉钉杯大学生大数据挑战赛 初赛 B:美国纽约公共自行车使用量预测分析 问题一 1 题目 Citi Bike是纽约市在2013年启动的一项自行车共享出行计划,由“花旗银行”(Citi Bank)赞助并取名为“花旗单车”(Citi Bike)。在曼哈顿,布鲁克…

PID算法:标准PID算法的一些改进措施

前面的几篇文章分别分享了PID算法的原理、增量式和位置式PID算法的区别、以及过程控制中一些重要的指标,感兴趣的朋友可以回看之前的文章或者自行查阅资料。 在实际项目中,使用数字PID算法对系统的被控量进行控制的时候,有时候并不是仅仅的使…

面试之可重复读是否可以解决幻读

可重复读(repeatable read)定义:一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据时是一致的。 不过理论上 是会出现幻读的,简单的来说幻读指的是当用户读取某一范围的数据行时,另外一个事务又在该范围…

一个PDF怎么拆分成几个?这几个方法轻松拆分PDF!

在现代生活与工作的环境中,我们常常需要以高效的方式处理包含大量信息的PDF文件。在这种情况下,拆分这些文件成为一种理想的解决方案,以便更精准地管理和阅读这些信息。接下来,我们将深入探讨几种实用的PDF拆分技巧。 一、直观的…

postman-循环调用测试接口

此篇文章产生的背景是想针对接口做流控验证,检查流控是否奏效,便发现postman也能一次操作来循环调用接口,减少了一些开发测试工作,下面就看一下操作流程 目录 前置查看postman版本我的接口数据 具体操作步骤新建接口集选择接口集进…

FL Studio Producer Edition v21.0.3.3517 for Mac中文版解锁版下载

水果音乐编辑软件FL Studio Producer Edition v21.0.3.3517 for Mac中文版解锁版下载是兔八哥爱分享搜集到的Mac Os系统上一款功能齐全的音乐编曲工具,可以为需要创作高品质音乐曲目的专业和业余艺术家提供多轨录音,排序和混音。 借助FL Studio 21的帮助…