全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:5150
推到 Plurk!
推到 Facebook!

跨行程共享記憶體 - Memory mapping file

 
miyu
中階會員


發表:13
回覆:96
積分:91
註冊:2003-05-01

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-09-07 16:11:47 IP:61.219.xxx.xxx 未訂閱
要用, 當然要先建立... 就如同要結婚首先要把到美眉是一樣的 XD 首先呢, 先呼叫 CreateFile() 開啟一個檔案, 或是建立一個新檔. 這視你是臨時用用, 還是開啟那個檔起來處理裡面的資料. 這邊我只關心兩個參數, 其他的請自己去查 MSDN 第一個是 Access Mode, CreateFile() 可以用 Read, Write 或是 Read | Write = Access (R/W) 的模式開啟. 當然, 這看你打算怎麼去用這塊記憶體. (它是檔案, 存在磁碟機上, 不過, 當它被mapping的時候, 它也同時是記憶體) 第二個是 Share Mode, CreateFile() 可以指定 No Share, Share Read, Share Write, 或是 Share Read | Share Write = Share Access (Share R/W). 如果是 Debug 版, 你可以考慮指定成為 Share Read 或甚至是 Share Read/Write. 這樣你就可以用個 Hex Editor 開啟這個 Memory file, 然後監看, 甚至去偷改了. 出貨版當然是不理他, 設為 0 啦. 然後, 拿著 CreateFile() 傳回來的 Handle, 丟給 CreateFileMapping(), 去建立 Mapping File handle. 請注意, 一定要檢查 CreateFile() 的傳回值, 否則.. 後述. XD 當然, 這東西等於就是記憶體, 所以你要指定一個屬性: PAGE_READONLY, PAGE_READWRITE, PAGE_WRITECOPY. 第三個指的是, 當你要對這個 memory mapping 寫入任何東西時, OS 會 copy 一份專屬你的 page . 於是乎, 原始檔案就不會被作任何的改變. Memory mapping file 可以 support 到 16 EB (註1), 比你直接可用的 RAM 還大多了. 因此呢, 你要傳兩個 32 bits 的參數去表示檔案大小. 想利用目前檔案的 Size, 請傳入 0; 如果你想擴建這個檔案, 請你要指定好 size. 就像你在 Alloc memory 是一樣的. 最後一個工作, 就是實際把 File mapping 到虛擬記憶空間去. 請呼叫 MapViewOfFile() MapViewFile() 可以指定要從檔案的哪裡開始, 然後要 View 的空間範圍有多大. 畢竟, Memory mapping file support 16 EB, 而我們沒有這麼大的 Virtual Memory space 去 mapping. 成功之後它會傳回一個 PVIOD 的指標, 你就可以用這個指標開始 access 了, 就當它是 Memory 一樣使用. 作完這些, 你就可以開始使用 Memory mapping file 了. 好吧, 我知道有人會抱怨: 我不是要處理超大型物件, 只是要跨行程分享一些資料, 能不能不要建立一個檔案啊, 我們有安全上的考量, 我們有那樣這樣的考量... 可以的, 只要你把 INVALID_HANDLE_VALUE 當成參數傳給 CreateFileMapping() 的 file handle, 如此, 這個 mapping 就不需要檔案, 可以直接建立在 swap file 中. 這也是為什麼我在前面提到一定要 check CreateFile() 傳回來的參數是否正確的原因. 因為 CreateFile() 如果 fail, 傳回來的參數也正好是 INVALID_HANDLE_VALUE. XD 好孩子在用完 OS 以後一定要記得歸還喔! UnmapViewFile() 用來歸還 MapViewFile() mapping 的 virtual address. 不過為了確保東西寫回去了, 最好是先呼叫一下 FlushViewOfFile(). CreateFileMapping() 跟 CreateFile() 傳回的都是 Handle, 所以請用 CloseHandle() 關掉就可以了. 另外, MapViewFile() 為什麼需要指定從檔案的哪裡開始呢... 因為, 當你 Mapping 檔案到 Virtual Memory 時, OS 必需要能夠找到足夠的空間 mapping. 假設你有一個 200GB 的檔案, 檔案太大了, 無法一次 mapping 到 Virtual Memory 去, 你只好先用 CreateFileMapping() 開啟這個檔, 然後用 MapViewFile() 去 mapping 某一段, 用完以後 UnmapViewFile() 先釋放, 然後再呼叫 MapViewFile() 去 mapping 下一段... 直到你都用完了, 才呼叫 CloseHandle() 去釋回 CreateFileMapping() 及 CreateFile() 的 Handle. 壞消息是, 在 Win9x/ME 中, 要被 Mapping 到記憶空間的檔案總大小, 不能比未被使用的記憶空間大... 即使你只是要 mapping 其中一小塊. 這個功能只有 WinNT support. 最後, 讓我們用一個行程間共享記憶體的範例當結束吧 XD 註1: Kilo-Byte = 2^10 Mega-Byte = 2^20 Giga-Byte = 2^30 Tera-Byte = 2^40 Peta-Byte = 2^50 Exa-Byte = 2^60 Zetta-Byte = 2^70 Yotta-Byte = 2^80 --- 小葵..小葵有很多的夢想 等待薰下班回家, 並準備晚飯跟洗澡水 薰回家的時候, 對你說一聲 歡迎回家 在休息的日子, 兩個人坐在屋外的走廊上, 品嚐著我親自作的點心 薰如果累了, 替他搥搥肩; 冷了, 和薰一起擠著被爐 但是, 但是... 小葵最大的心願是...成為薰的..成為薰的妻子
附加檔案:37041_MemMapFile.rar
happosai
高階會員


發表:93
回覆:228
積分:109
註冊:2002-09-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-09-15 13:41:27 IP:211.75.xxx.xxx 未訂閱
Memory Mapping File 真的不錯用,小弟的劣作 Lazy Password 也有用到喔 http://akk.fengsoft.com/LazyPassw.htm
ntust9015030
一般會員


發表:0
回覆:1
積分:0
註冊:2004-04-02

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-04-10 17:03:16 IP:61.228.xxx.xxx 未訂閱
請問一下..我該怎麼在共享memory中. 把我在其中一個process輸入的東西. 同時mapping到所有打開的process呢???
系統時間:2024-03-28 18:22:39
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!