3 回答

TA貢獻2037條經驗 獲得超6個贊
如果你有多個進程從同一個文件以只讀方式訪問數據,那么mmap很棒,這在我編寫的服務器系統類型中很常見。mmap允許所有這些進程共享相同的物理內存頁面,從而節省大量內存。
mmap還允許操作系統優化分頁操作。例如,考慮兩個程序; 程序A將1MB文件讀入使用malloc創建的緩沖區,程序B將1MB文件格式化為內存。如果操作系統必須將A的一部分內存交換掉,它必須將緩沖區的內容寫入交換,然后才能重用內存。在B的情況下,任何未修改的mmap頁面都可以立即重用,因為操作系統知道如何從他們mmap的現有文件中恢復它們。(操作系統可以通過最初將可寫mmap的頁面標記為只讀并捕獲seg錯誤來檢測哪些頁面未修改,類似于寫入時復制策略)。
mmap對于進程間通信也很有用。您可以在需要通信的進程中將文件映射為讀/寫,然后在mmap'd區域中使用同步原語(這是MAP_HASSEMAPHORE標志的用途)。
如果您需要在32位計算機上使用非常大的文件,那么mmap的一個地方可能很尷尬。這是因為mmap必須在進程的地址空間中找到一個連續的地址塊,該地址空間足夠大,以適應所映射文件的整個范圍。如果您的地址空間變得碎片化,這可能會成為一個問題,您可能有2 GB的地址空間可用,但沒有單獨的范圍可以適合1 GB的文件映射。在這種情況下,您可能必須將文件映射到比您想要的更小的塊中。
mmap作為讀/寫替代品的另一個潛在尷尬是你必須在頁面大小的偏移量上開始映射。如果您只想在偏移X處獲取一些數據,則需要修復該偏移量,以便與mmap兼容。
最后,讀/寫只是你的方式可以與某些類型的文件的工作。mmap不能用于管道和ttys之類的東西。

TA貢獻1856條經驗 獲得超5個贊
我發現mmap()不具有優勢的一個領域是讀取小文件(16K以下)。與僅執行單個read()系統調用相比,讀取整個文件的頁面錯誤開銷非常高。這是因為內核有時可以在您的時間片中完全滿足讀取,這意味著您的代碼不會被切換掉。由于頁面錯誤,似乎更有可能安排另一個程序,使文件操作具有更高的延遲。

TA貢獻1773條經驗 獲得超3個贊
mmap
當您對大文件進行隨機訪問時具有優勢。另一個優點是您可以通過內存操作(memcpy,指針算術)訪問它,而無需擔心緩沖。當結構大于緩沖區時,使用緩沖區時,正常I / O有時會非常困難。處理它的代碼通常很難正確,mmap通常更容易。這就是說,工作時有一些陷阱mmap
。正如人們已經提到的那樣,mmap
設置成本非常高,因此僅適用于給定尺寸(從機器到機器)不同。
對于對文件的純順序訪問,它也不總是更好的解決方案,盡管適當的調用madvise
可以緩解問題。
您必須小心架構的對齊限制(SPARC,itanium),使用讀/寫IO緩沖區通常是正確對齊的,并且在取消引用轉換指針時不會陷阱。
您還必須小心,不要在地圖外訪問。如果在地圖上使用字符串函數,并且文件末尾不包含\ 0,則很容易發生。當文件大小不是頁面大小的倍數時,它將在大多數情況下工作,因為最后一頁填充為0(映射區域的大小始終為頁面大小的倍數)。
- 3 回答
- 0 關注
- 754 瀏覽
添加回答
舉報