什么時候用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 參數決定的。
`````稀疏提交的內存映射文件
--看來需要把虛擬內存那章一起看看了~~~~