一、mmap內存映射主要用在哪裡
mmap內存映射是一種將文件或其他對象映射到進程地址空間的機制,主要用於以下場景:
1. 文件映射:在許多操作系統中,可以通過mmap將一個文件的整個內容映射到進程的地址空間中。這種技術被廣泛應用於一些高效的文件操作,如資料庫系統,谷歌的大量的Web伺服器和開發一些離線處理的大數據應用。
2. 共享內存:mmap還可以將一塊共享內存映射到多個進程的地址空間中,這些進程可以直接通過訪問共享內存來交換數據,可以在這些進程間實現高效的通信。
3. 匿名映射:通過mmap可以在進程的地址空間中分配一塊虛擬內存,來實現不同進程之間的數據共享,這種匿名映射的內存映射技術被廣泛應用於Unix/Linux系統中的共享庫,而且在現代操作系統中也是非常有用的。
二、mmap內存映射函數的參數
mmap函數在使用時需要傳遞四個必要的參數,它們依次是:
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
1. addr:可選的指定映射的開始地址,通常將它設置為0,讓系統自動選擇一個未使用的地址作為映射的地址,這是一個好的習慣。
2. length:映射的大小,單位是位元組。
3. prot:映射區域的保護方式,可以是下面幾個選項中的一個或多個組合:
- PROT_EXEC:表示可執行的代碼
- PROT_READ:表示可讀
- PROT_WRITE:表示可寫
- PROT_NONE:表示不可訪問
4. flags:控制映射區域的各種屬性,可以通過以下的選項進行組合:
- MAP_PRIVATE:建立一個寫入時拷貝(COW)的私有映射,不會改變原對象。
- MAP_SHARED:對映射區域的寫入數據會複製迴文件
5. fd:需要映射的文件描述符。
6. offset:文件映射的偏移量,通常將它設置為0,表示從文件頭開始。
三、mmap內存映射原理
mmap內存映射是基於虛擬內存進行的,它允許應用程序像訪問內存一樣訪問磁碟上的文件,實際上是將文件的一段內容直接映射到進程地址空間的一段區域中,這導致了一系列的優點:
- 有時不需要將整個文件都讀入內存即可開始工作
- 當需要更新文件時,不需要顯式地拷貝到磁碟上
- 不會造成page cache的污染,同時內存限制也大大增加
它的底層實現利用了虛擬內存的一個非常重要的好處,即虛擬內存能夠將物理內存和交換空間(磁碟)組合在一起使用。CPU需要訪問進程的某個虛擬地址時,會計算出這個地址在物理內存或者磁碟上的位置,如果在物理內存上,那麼直接訪問;否則就會將物理內存中不常用的頁替換到磁碟上,然後再從磁碟上讀入需要的頁。
四、mmap內存映射內核
mmap內存映射是由操作系統內核虛擬內存系統的具體實現來支持的。具體來說,內核在mmap函數調用時,會向虛擬內存子系統發送一個請求,讓它將一個虛擬內存區域映射到用戶進程的地址空間中。當進程訪問這個虛擬內存區域時,虛擬內存子系統會將對應的數據從文件中讀入,或者將數據寫回磁碟上。
這個虛擬內存區域是由用戶進程管理的,稱為內存映射區域。在虛擬內存系統中,被映射文件的每一個頁都有多個副本,既可以在文件中存在,也可以在內存中存在。因此,當進程對一個虛擬內存區域中的某個頁進行訪問時,虛擬內存系統會將這個頁映射到多個虛擬內存區域中,並將這些虛擬內存區域轉換為物理頁框,使得這些虛擬內存區域實際上都指向了同一個物理頁。
五、mmap內存映射大小限制
在64位系統中,由於地址空間的大小可以達到2^64個位元組,因此可以創建非常大的內存映射區域。但是在32位系統中,由於地址空間的大小只有2^32個位元組,因此內存映射的大小受到了一定的限制,在一些系統中可以定義一些參數來調整限制的大小。
六、mmap內存映射 文件為空
當被映射的文件為空時,根據函數的flags參數的不同,mmap內存映射的行為也有所不同。
1. 如果標誌選項包含MAP_PRIVATE,則映射區域中的內容將被初始化為0。
2. 如果標誌選項包含MAP_SHARED,則映射區域的是未定義的,並且對該區域的訪問會產生匯流排錯誤(bus error)。
七、mmap內存映射bus error
當mmap映射區域為空時,在對映射區域進行寫入等操作時,會產生匯流排錯誤(bus error)。這是因為在嘗試使用空的映射區域時,訪問的內存地址無效。這時可以使用mmap函數的MAP_ANONYMOUS參數來初始化該映射區,例如:
char *ptr = mmap(NULL, sizeof(char)*512, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
這樣就可以正確初始化一個空的映射區域了。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/287209.html