当前位置:首页 » 电脑资讯 » 为什么内存映射文件需要加锁

为什么内存映射文件需要加锁

发布时间: 2022-03-14 15:01:13

㈠ 内存映射文件问题

在软件的开发过程中,有时需要控制一些程序使他们不能同时运行,也就是多个程序间互斥运行(还包括禁止同一程序运行多个实例)。针对这一问题,我们在Visual C++6.0中利用内存映射文件实现了多个程序间的互斥运行。内存映射文件可以创建一个没有和磁盘文件相联系的内存对象,将文件的信息映射到一个进程的地址空间上,我们可以访问该文件中的数据,就如同它位于内存中一样。同时,在程序设计中可以给内存映射文件对象起一个名字,这个名字在整个系统中是唯一的,这个名字可以在多个进程之间共享,通过名字共享能实现进行信息交换,进而实现多个程序间的互斥运行。

在讲述具体的编程方法之前,让我们先介绍和内存映射文件操作有关的几个重要的函
CreateFileMapping的函数为指定的文件创建一个文件映射对象,该函数的原形如下:

HANDLE CreateFileMapping(HANDLE hFile,//用于映射的文件句柄 LPSECURITY?ATTRIBUTES FileMappingAttributes,//内存映射文件的安全描述符 DWORD Flprotect,//文件映射对象的最大长度的高32位 DWORD dwMaximumSizelow,//最大长度的低32位 LPCTSTR IPNAME//指定这个内存映射文件的名字)

值得注意的是,参数如果是OXFFFFFFFF,将在操作系统虚拟内存页面替换文件中创建文件映射对象,而不是使用磁盘文件,同时必须给出这个映射对象的大小。
NAO VUEWIFFILE函数将文件的视图映射到一个进程地址空间上,返回LPVOID类型的内存指针。通过它,就可以直接访问文件视图中的信息。

LPVOID MAP VIEWLFFILE(HANDLE HFILEMAPPINGOBUCT,//映射文件对象句柄 DWORD DWDESIREDACCESS,//访问模式 DWORD DWFILEOFFSETHIGH,//文件偏移地址的高32位 DWORD DWFILEOFFSETHIGH,//文件偏移地址的低32位 DWORD DWNUMBEROFBYTESTOMAP//映射视图的大小)

在Visual c++6.0中我们用默认方式生成基于对话框的应用程序,在程序的初始化阶段,在CwinApp生类的Initln_stance函数的开始处,添加以下代码:

(//创建内存映射文件对象,mu_texRunning是其名字,所有需要互斥运行 //的程序都使用这个名字(这些代码对于需要互斥运行的程序是通用的)HANDLE hMap=CreateFileMapping((HANDLE)0Xffffffffnull,PAGE_READWRLTE,0,128,"Mu_texRunning") if(hMap==NULL)//如果创建失败 (AfxMessageBox("创建用于互斥运行的内存映文件对象失败!”,MB?OK MB??ICLNSTOP);

return FALSE;//退出此程序)

//如果已经存在这个同名对象,说明已有需要互斥的其他程序运行了

else if(GetLastError( )==ER_ROR_ALREADY_EXISTS)

(LPVOID ipMen=MapViewOFFile(hMap,FILE_MAP_WRITE,0,0,0);

Cstring str=(char*)ipMem;//获得已在运行的程序的描述信息

UnmapViewofFile(lpMem);//解除映射图

CloseHandle(hMap);//关闭此对象

AfxMessageBox(str,MB_ok MB_ICONSTOP);显示有关的描述信息

Return FALSE;//退出此程序)

Else//经过上面的检查,说明这是第一个运行的互斥程序

(LPVOID ip_mem=MapViewofFile(hMap,FILE_MAP_WRITE,0,0,0);

//这里可写入该程序运行的描述信息,上面的错误提示就是这信信息

strcpy((char*)lpMem,"xxx程序正在运行!”);

UnmapViewofFile(lpMem);//解除映射图)

//下面可以继续执行函数INITIN?STANCE原有的代码了

AfxEnableControl_comtainer();

//当程序运行结束了,要记住调用CHANDIE(HMAP)关闭这个对象句柄,//这里可以在Initinstance函数最后returnFALSE之前调用

CloseHandle(hMap);//关闭内存映文件对象句柄 RETURN false;)以上的程序在Visual C++6.中已调试通过。其他非对话框类型的程序可以在各自的初始化和终止阶段添加类似的代码,只是如果内存映射文件对象的句柄hMap可能在不同函数中使用,那就要将其定义成CwinApp生类的成员变量或是全局变量了。

㈡ 对内存映射文件写入,程序关闭后,文件并没有更新其内容

映射部分是否是与专用段落或是未被锁定。请核实

㈢ 内存映射是怎么回事

内存映射文件是由一个文件到一块内存的映射,使进程虚拟地址空间的某个区域与磁盘上某个文件的部分或全部内容的建立映射。
建立映射后,通过该区域可以直接对被映射的磁盘文件进行访问.而不必执行文件I/O操作也无需对文件内容进行缓冲处理。
就好像整个被映射的文件都加载到了内存一样,因此内存文件映射非常适合于用来管理大文件。

内存映射文件对程序的提速,只在处理大文件或非常频繁的文件读写操作时效果才明显。
通过内存映射,相当于将磁盘上的文件所在空间建立成一块虚拟内存,程序访问时可按内存的方式进行,省去了普通io方式的一些环节,其实真正要读写操作时,会进行换页,将这些个“虚拟内存”读到物理内存中。
总之,内存映射文件是应用虚拟内存的技术来达到加速处理的

㈣ 内存映射文件的使用

为什么要内存映射?
ReadFile本来就不是一次把文件全部读到内存。

㈤ 内存映射文件的内存文件

内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,而且在对该文件进行操作之前必须首先对文件进行映射,就如同将整个文件从磁盘加载到内存。由此可以看出,使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件的回写以及释放内存块等步骤,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。另外,实际工程中的系统往往需要在多个进程之间共享数据,如果数据量小,处理方法是灵活多变的,如果共享数据容量巨大,那么就需要借助于内存映射文件来进行。实际上,内存映射文件正是解决本地多个进程间数据共享的最有效方法。
内存映射文件并不是简单的文件I/O操作,实际用到了Windows的核心编程技术--内存管理。所以,如果想对内存映射文件有更深刻的认识,必须对Windows操作系统的内存管理机制有清楚的认识,下面给出使用内存映射文件的一般方法:
首先要通过CreateFile()函数来创建或打开一个文件内核对象,这个对象标识了磁盘上将要用作内存映射文件的文件。在用CreateFile()将文件映像在物理存储器的位置通告给操作系统后,只指定了映像文件的路径,映像的长度还没有指定。为了指定文件映射对象需要多大的物理存储空间还需要通过CreateFileMapping()函数来创建一个文件映射内核对象以告诉系统文件的尺寸以及访问文件的方式。在创建了文件映射对象后,还必须为文件数据保留一个地址空间区域,并把文件数据作为映射到该区域的物理存储器进行提交。由MapViewOfFile()函数负责通过系统的管理而将文件映射对象的全部或部分映射到进程地址空间。此时,对内存映射文件的使用和处理同通常加载到内存中的文件数据的处理方式基本一样,在完成了对内存映射文件的使用时,还要通过一系列的操作完成对其的清除和使用过资源的释放。这部分相对比较简单,可以通过UnmapViewOfFile()完成从进程的地址空间撤消文件数据的映像、通过CloseHandle()关闭前面创建的文件映射对象和文件对象。

㈥ 内存映射文件的原理

讲点基础的你了解了再去看那些资料就好懂多了。
1。内存映射文件简单概述
内存文件映射也是Windows的一种内存管理方法,提供了一个统一的内存管理特征,使应用程序可以通过内存指针对磁盘上的文件进行访问,其过程就如同对加载了文件的内存的访问。通过文件映射这种使磁盘文件的全部或部分内容与进程虚拟地址空间的某个区域建立映射关联的能力,可以直接对被映射的文件进行访问,而不必执行文件I/O操作也无需对文件内容进行缓冲处理。内存文件映射的这种特性是非常适合于用来管理大尺寸文件的。
2。使用内存映射文件的一般流程
而在某些特殊行业,经常要面对十几GB乃至几十GB容量的巨型文件,而一个32位进程所拥有的虚拟地址空间只有232 = 4GB,显然不能一次将文件映像全部映射进来。对于这种情况只能依次将大文件的各个部分映射到进程中的一个较小的地址空间。这需要对上面的一般流程进行适当的更改:
1)映射文件开头的映像。
2)对该映像进行访问。
3)取消此映像
4)映射一个从文件中的一个更深的位移开始的新映像。
5)重复步骤2,直到访问完全部的文件数据。

㈦ 为什么要内存映射

内存映射(mmap)是一种内存映射文件的方法,即将一个文件或者其他对象映射到进程的地址空间,实现文件磁盘地址和应用程序进程虚拟地址空间中一段虚拟地址的一一映射关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写藏页面到对应的文件磁盘上。应用程序处理映射部分如同访问主存。(1)线程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域。

先在用户空间调用库函数mmap,并在进程当前进程的虚拟地址空间中,寻找一段空闲的满足要求的连续虚拟地址作为内存虚拟映射区域,对此区域初始化并插入进程的虚拟地址区域链表或树中。

(2)系统在内核空间调用内核函数mmap,实现文件物理地址和进程虚拟地址之间的一一映射关系。

(3)进程发起堆这片映射空间的访问

进程读写操作访问虚拟地址,查询页表,发现这一段地址并不在内存的物理页面上,因为虽然建立了映射关系,但是还没有将文件从磁盘移到内存中。由此发生缺页中断,内核请求从磁盘调入页面。调页过程先在交换缓存空间(swap cache)中查找,若没有则通过nopage函数把缺失页从磁盘调入内存。之后进程会对其做读写操作,若写操作改变了页面内容,一段时间后系统会自动回写脏页面到磁盘中。(修改过的脏页面不会立即更新到文件中,可以调用msync来强制同步,写入文件)

㈧ 如何对mmap区域的数据进行加锁

如果内存映射文件是将文件全部读取到内存中,那么“内存映射文件”和你直接从文件读取数据,全部装入内存就没有区别了,内存映射文件也就没有存在的意义了。 内存映射文件的原理是通过数据访问局部性这个原理来提高性能的。什么叫数据访问局部性呢?我们从统计学意义上分析,如果你读取文件中某个地方的数据,那么你接下来读取的数据在之前读取地址附近的概率,要比读取很远的地方的数据的概率要高。 那么,如果操作系统得到请求,你要获取某个数据,它在读取这个数据的时候,顺带手将这一块的数据都读取到内存中。也许接下来很不幸,你读取的数据不在操作系统预取的范围内,但是这是少数情况。多数情况是,你接下来再读的数据,内存中已经有了,此时操作系统无需再访问磁盘,直接从内存中返回。 虽然这比一次性全部读进内存,100%的数据都能访问到要稍微逊色一些,但是我们用很经济的代价(可能只要原数据10%的内存)得到了近乎完美的性能(和完全读到内存相比性能可能相差10%)。 是不是这样一来性能就提高了?内存映射文件的含义就是,操作系统透明处理了很多加载、更新、回写缓存的操作,使得开发者看上去像是读取文件,但是结果是更快实现了IO的存取。同时又避免数据过大不能一次性读取到内存的问题。

㈨ 什么是内存映射文件 高手进来

将文件内容(可部分可整个映射到内存地址上),操作文件时就只操作内存地址就行了,其它的操作系统帮你做。

热点内容
每天晚上时不时做噩梦是为什么 发布:2024-05-05 09:43:11 浏览:149
手机电源适配器为什么不发热 发布:2024-05-05 09:41:36 浏览:684
苹果设置中为什么出现英文字母 发布:2024-05-05 09:38:00 浏览:950
vivo手机系统服务为什么找不到 发布:2024-05-05 09:33:54 浏览:737
为什么煮东西先用火 发布:2024-05-05 09:31:51 浏览:25
为什么射击游戏老是不好玩 发布:2024-05-05 09:21:18 浏览:534
飞猪会员第二次订房为什么不便宜 发布:2024-05-05 09:13:24 浏览:670
微信榴莲千层为什么那么便宜 发布:2024-05-05 09:11:54 浏览:926
苹果xr为什么接解码耳放无声音 发布:2024-05-05 09:05:34 浏览:732
微信支付为什么出现上传身份证照片 发布:2024-05-05 09:00:40 浏览:132