Memory
類 Unix 系統中記憶體映射的概念
有人可以以一種易於理解的方式解釋類 Unix 系統中的記憶體映射概念(通過 mmap() 系統呼叫實現)嗎?我們什麼時候需要這個功能?
考慮:兩個程序可以同時打開同一個文件進行讀寫,因此兩者之間可以進行某種通信。
當程序 A 寫入文件時,它首先用一些數據填充它自己的程序特定記憶體中的緩衝區,然後呼叫
write
將緩衝區復製到核心擁有的另一個緩衝區(實際上,這將是一個頁面記憶體條目,它核心將標記為臟並最終寫回磁碟)。現在程序 B 從同一文件中的同一點讀取;
read
將頁面記憶體中相同位置的數據複製到 B 記憶體中的緩衝區中。請注意,需要兩個副本:首先將數據從 A 複製到“共享”記憶體,然後再次從“共享”記憶體複製到 B。
A 可以
mmap
用來使頁面高速記憶體記憶體在其自己的地址空間中直接可用。現在它可以將其數據直接格式化到相同的“共享”記憶體中,而不是填充中間緩衝區並避免複製。同樣,B 也可以
mmap
將頁面直接放入它的地址空間。現在它可以直接訪問 A 放入“共享”記憶體中的任何內容,而無需將其複製到單獨的緩衝區中。(如果您真的想將此方案用於 IPC,顯然需要某種同步,但這超出了範圍)。
現在考慮 A 被儲存在該文件的任何設備的驅動程序替換的情況。通過使用 訪問文件
mmap
,B仍然避免了冗餘副本(DMA 或任何進入頁面記憶體的內容是不可避免的,但不需要再次將其複製到 B 的緩衝區中)。當然,也有一些缺點。例如:
- 如果您的設備和作業系統支持非同步文件 I/O,您可以避免使用它來阻止讀取/寫入……但是讀取或寫入 mmapped 頁面可能會導致您無法直接處理的阻塞頁面錯誤(儘管您可以嘗試避免使用
mincore
等)- 它不會阻止您嘗試讀取文件的末尾,或幫助您以一種很好的方式附加到它(您需要檢查長度或明確
truncate
文件更大)