什么时候用memory-mapped files:
1.System use it to load and execute .exe and dll files.
2.Use memory-mapped files to access a data file on disk.
3.allow multiple processes running on the same machine to share data with each other.
------------------------------------------------------------------------------------------------------
用途一:使用mapping file executables and dlls
当调用createProcess时候,系统做了以下的事情:
1.locates CreateProcess 中指定的the .exe file,失败则return false
2.创建新的process kernel object
3.creates a private address space for new process
4.reserves a region of address space large enough to contain the .exe file.The desired location of this region is specified by the .exe file itself.by default ,base address is 0x00400000 .You can change it by create your app .exe fiel using linker’s /BASE option.
5.the systems notes that the physical storage baking the reserved region is in the .exe file on disk instread of the system’s paging file.(系统注意到,支持已保留区域的物理存储区域是在磁盘上的.exe 文件而不是在系统页面中)
当。exe 被mapped into the process address space,系统访问.exe的一个区域,那里列出了.exe含有的dll,然后系统利用 LoadLibrary for each dlls。系统map dll时候,如果dll的 preferred base address 被占据或者不够大,dllwill try to find another region of address space to reserve for the dll。如果dll 被设定了/Fixed when it build,也就是不支持重定位,那么加载失败。
如果加载dll或者exe 失败,弹出对话框并且释放申请的地址空间。
after all .exe dll mapped into the process address space, system can begin exec the .exe file starup code. the sys takes care of all paging,buffering, and caching. 例如,如果一段代码访问了一个并不在主存的地址,那么一个错误产生,系统察觉到错误并且自动的调入page of code from the files image into a page of RAM。
the sys maps the page of ram to the proper location in the process address and allows the thread to continue.
当为一个app创建第二个实例时,系统只是简单的打开另外一个memory-mapped view of file-mapping object that identifies the exec files image and create a new process object and a new thread object.利用内存映射文件,多个实例可以共享代码和数据。实际上,file 是分为多个section ,多个节均对齐于页边界。如果一个instance of the app 修改了全局变量,系统应用了copy-on-write 机制,复制修改的页面,并更新实例的file-mapping view。当我们调试程序时同样的事情会发生,debuger modify code,sys use cow again。
当一个进程被加载,系统检查其所有映射文件页,系统将所有通常用cow保护的页面提交给存储系统,这些页面仅仅是被提交,当文件被访问的时候,系统读入相应的页面,如果页面没有被修改,那么他们可以被换出,如果已经修改,系统将修改过的页面转入已经提交的页面之一(这点很晦涩啊 system swaps the modified page to one of the perviously committed pages in the paging file ,怎么翻译呢~~~~ :( )
------------------------------------------------------------------------------------------------------
在可执行文件或者dll中共享静态变量
------------------------------------------------------------------------------------------------------
内存映射数据文件
例子:要把一个文件所有字节倒置
如果利用file mapping 我们告诉系统使用一个虚拟空间的区域来倒置文件,然后告诉把文件的第一个字节映射到保留空间的第一个字节,然后就像处理内存中的字符串一样处理文件即可,引文系统会帮助你完成文件缓存以及调页等工作。
使用流程:
1.创建一个file kernel object that identifies the file on disk that you want to use as a memory –mapped file
2.创建一个file mapping kernel object 告诉系统文件的大小,以及你准备如何访问文件
3.告诉系统map all或者部分文件到你的进程地址空间
当使用结束后要:
1告诉系统 unmap file-mapping kernel object form your process add
2cloes filemapping kernel object
3close file kernel object
---------
具体步骤
--1. 创建文件内核对象
CreateFile
失败返回 INVALID_HANDLE_VALUE = –1 一般来说windows func 失败return null这个比较特殊
createfile dwdesiredAccess 需要设置为 GENERIC_READ 或者 GENERIC_WRITE
--2. 创建file-mapping 内核对象
CreatefileMapping(HANDLE,PSECURITY_ATTRIBUTES,DWORD fdwProtect,DWORD dwMaximumsizeHigh,DWORD dwMaximumSizeLow,PCTSTR pszName);
第一个参数使用createfile 返回的handle。psa一般使用默认null。当创建一个file mapping object 时候,系统并不会 马上保留一个地址空间,然后将file映射到这个区域。但很i,当系统map时候,系统必须知道为physical storage分配什么样的保护属性,第三个参数指明了这些。
后面两个参数指明file的大小,ensure enouth physical storage is available for the file-mapping object.
high指明高32位,low指明低32位。如果想创建一个反应现在文件大小的map,均传0.
pszName 用于与其它进程共享内存映射文件
--3.将文件数据map to process address space
使用这个函数
PVOID MapViewOfFile(HANDLE hfileMappingObject,dwDesireaccess,dwFileOffsetHigh,dwFileOffsetLow,dwNumberOfbytestomap)
文件没必要一次全映射,一次映射一部分,这一部分成为一个view
首先通过high和low 指定开始映射的字节
其次是指定映射多大,0则映射到文件尾部。
--4.unmapping the file data from the process address space
UnmapviewOfFile(PVOID pvBaseAdddress);
参数使用mapview的返回值
如果强制write back to disk 则使用 FlushViewOfFile(PVOID pvAddress,SIZE_T dwNumberOfBytesToFlush)
第一个地址是想要开始flush的地址
--5.关闭filemapping object 以及file object
-----------------------------------------------------------------------------------
使用filemap 在进程之间共享数据
例子:
app开始时候,系统调用createfile to open .exe file onthe disk。sys call creatFileMapping to create filemapping object.然后系统调用 mapviewofffileEX (with sec_image flag to point out it is a pe file),So that the file’s image is mapped to the address of the first byte of exectuable code of this mapped view. System creates the primary thread , puts the address of the first byte of exec code of this mapped view in the thread instruction pointer,and then lets the cpu start exec the code.
If user 再启动同一个app,sys 看到file-mapping已经存在了,系统maps a view of file a second time,this time in the context of the newly created process address space.
像所有内核对象一样,有三种方法共享他,继承,命名对象以及赋值handle。
···页文件支持的内存映射文件
许多应用程序运行是产生数据需要和其他进程共享如果必须在硬盘建立文件才可以共享,那么效率很低。因此微软提供了由system paging file 支持的 file mapping。不需要createfile ,只需要在调用createFilemapping 的时候传进一个 INVALID_HANDLE_VALUE 作为hFile 参数即可。 映射文件大小同样是由high 和low 参数决定的。
`````稀疏提交的内存映射文件
--看来需要把虚拟内存那章一起看看了~~~~