linux內存映射函數mmap

  
          內存映射,簡而言之就是將用戶空間的一段內存區域映射到內核空間,映射成功後,用戶對這段內存區域的修改可以直接反映到內核空間,同樣,內核空間對這段區域的修改也直接反映用戶空間。那麼對於內核空間<---->用戶空間兩者之間需要大量數據傳輸等操作的話效率是非常高的。內存映射過程就是依據進程PCB控制塊中內容找到內存單元的相應地址通過頁表映射到物理內存中,

是一個把普遍文件映射到用戶空間的內存區域的示意圖。

      mmap函數是unix/linux下的系統調用,系統調用並不是完全爲了用於共享內存而設計的。它本身提供了不同於一般對普通文件的訪問方式,進程可以像讀寫內存一樣對普通文件的操作。而Posix或系統V的共享內存IPC則純粹用於共享目的,當然mmap()實現共享內存也是其主要應用之一。
          mmap系統調用使得進程之間通過映射同一個普通文件實現共享內存。普通文件被映射到進程地址空間後,進程可以像訪問普通內存一樣對文件進行訪問,不必再調用read(),write()等操作。mmap並不分配空間, 只是將文件映射到調用進程的地址空間裏(但是會佔掉你的 virutal memory), 然後你就可以用memcpy等操作寫文件, 而不用write()了.寫完後,內存中的內容並不會立即更新到文件中,而是有一段時間的延遲,你可以調用msync()來顯式同步一下, 這樣你所寫的內容就能立即保存到文件裏了.這點應該和驅動相關。 不過通過mmap來寫文件這種方式沒辦法增加文件的長度, 因爲要映射的長度在調用mmap()的時候就決定了.如果想取消內存映射,可以調用munmap()來取消內存映射

void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset)</span

mmap用於把文件映射到內存空間中,簡單說mmap就是把一個文件的內容在內存裏面做一個映像。映射成功後,用戶對這段內存區域的修改可以直接反映到內核空間,同樣,內核空間對這段區域的修改也直接反映用戶空間。那麼對於內核空間<---->用戶空間兩者之間需要大量數據傳輸等操作的話效率是非常高的

start:要映射到的內存區域的起始地址,通常都是用NULL(NULL即爲0)。NULL表示由內核來指定該內存地址  

[cpp] view plain copy

 print?
length:要映射的內存區域的大小  

[cpp] view plain copy

 print?
prot:期望的內存保護標誌,不能與文件的打開模式衝突。是以下的某個值,可以通過or運算合理地組合在一起  
PROT_EXEC //頁內容可以被執行  
PROT_READ  //頁內容可以被讀取  
PROT_WRITE //頁可以被寫入  
PROT_NONE  //頁不可訪問  

[cpp] view plain copy

 print?
flags:指定映射對象的類型,映射選項和映射頁是否可以共享。它的值可以是一個或者多個以下位的組合體  
MAP_FIXED :使用指定的映射起始地址,如果由start和len參數指定的內存區重疊於現存的映射空間,重疊部分將會被丟棄。如果指定的起始地址不可用,操作將會失敗。並且起始地址必須落在頁的邊界上。  
MAP_SHARED :對映射區域的寫入數據會複製迴文件內, 而且允許其他映射該文件的進程共享。  
MAP_PRIVATE :建立一個寫入時拷貝的私有映射。內存區域的寫入不會影響到原文件。這個標誌和以上標誌是互斥的,只能使用其中一個。  
MAP_DENYWRITE :這個標誌被忽略。  
MAP_EXECUTABLE :同上  
MAP_NORESERVE :不要爲這個映射保留交換空間。當交換空間被保留,對映射區修改的可能會得到保證。當交換空間不被保留,同時內存不足,對映射區的修改會引起段違例信號。  
MAP_LOCKED :鎖定映射區的頁面,從而防止頁面被交換出內存。  
MAP_GROWSDOWN :用於堆棧,告訴內核VM系統,映射區可以向下擴展。  
MAP_ANONYMOUS :匿名映射,映射區不與任何文件關聯。  
MAP_ANON :MAP_ANONYMOUS的別稱,不再被使用。  
MAP_FILE :兼容標誌,被忽略。  
MAP_32BIT :將映射區放在進程地址空間的低2GB,MAP_FIXED指定時會被忽略。當前這個標誌只在x86-64平臺上得到支持。  
MAP_POPULATE :爲文件映射通過預讀的方式準備好頁表。隨後對映射區的訪問不會被頁違例阻塞。  
MAP_NONBLOCK :僅和MAP_POPULATE一起使用時纔有意義。不執行預讀,只爲已存在於內存中的頁面建立頁表入口。  

[cpp] view plain copy

 print?
fd:文件描述符(由open函數返回)  

[cpp] view plain copy

 print?
offset:表示被映射對象(即文件)從那裏開始對映,通常都是用0。 該值應該爲大小爲PAGE_SIZE的整數倍  

返回說明  
成功執行時,mmap()返回被映射區的指針,munmap()返回0。失敗時,mmap()返回MAP_FAILED[其值爲(void *)-1],munmap返回-1。errno被設爲以下的某個值   


發佈了66 篇原創文章 · 獲贊 17 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章