mmap/munmap是常用的乙個系統呼叫,使用場景是:分配記憶體、讀寫大檔案、連線動態庫檔案、多程序間共享記憶體。
mmap/munmap函式宣告如下:
#include void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *addr, size_t length);
prot:記憶體區域的讀/寫/執行屬性。
flags:記憶體對映的屬性,共享、私有、匿名、檔案等。
fd:表示這是乙個檔案對映,fd是開啟檔案的控制代碼。
下面是prot對應的引數組合:
#define prot_read 0x1 /* page can be read */flags引數組合有:#define prot_write 0x2 /* page can be written */
#define prot_exec 0x4 /* page can be executed */
#define prot_sem 0x8 /* page may be used for atomic ops */
#define prot_none 0x0 /* page can not be accessed */
#define prot_growsdown 0x01000000 /* mprotect flag: extend change to start of growsdown vma */
#define prot_growsup 0x02000000 /* mprotect flag: extend change to end of growsup vma */
#define map_shared 0x01 /* share changes */---------建立乙個共享對映的區域,多個程序可以對映到乙個檔案,掐程序可以看到對映內容的改變,修改後內容會同步到磁碟中。
#define map_private 0x02 /* changes are private */--建立乙個私有的寫時複製的對映,其他程序看不到對映內容的改變,也不會同步到磁碟中。
#define map_fixed 0x10 /* interpret addr exactly */-使用指定的對映起始位址,如果有start和len引數指定的記憶體區重疊於現存的對映空間,重疊部分將會被丟棄。如果指定起始位址不可用,操作將會失敗。並且起始位址必須落在頁的邊界上。
#define map_anonymous 0x20 /* don't use a file */---匿名對映,對映區不與任何檔案關聯。此時fd應設定為-1。
#ifdef config_mmap_allow_uninitialized
# define map_uninitialized 0x4000000 /* for anonymous mmap, memory could be uninitialized */
#else
# define map_uninitialized 0x0 /* don't support this flag */
#endif
#define map_growsdown 0x0100 /* stack-like segment */--------------告訴核心vm系統,對映區可以向下擴充套件。
#define map_denywrite 0x0800 /* etxtbsy */
#define map_executable 0x1000 /* mark it as an executable */
#define map_locked 0x2000 /* pages are locked */-------------------鎖定對映區頁面,從而防止頁面被交換出記憶體。
#define map_noreserve 0x4000 /* don't check for reservations */
#define map_populate 0x8000 /* populate (prefault) pagetables */---對檔案對映來說,會提前預讀檔案內容到對映區域,只支援私有對映。
#define map_nonblock 0x10000 /* do not block on io */--------------和map_populate一起使用時才有意義。不執行預讀,只為已存在與記憶體中的頁面建立頁表入口。
#define map_stack 0x20000 /* give out an address that is best suited for process/thread stacks */
根據mmap是否對映到檔案、是共享還是私有對映,將對映型別分成四類,使用場景如下:
場景私有影射
共享對映
匿名對映
通常用於記憶體分配
fd=-1,flags=map_anonymous|map_private
通常用於程序間記憶體共享,常用於父子程序之間通訊。
fd=-1,flags=map_anonymous|map_shared
檔案對映
通常用於載入動態庫
flags=map_private
通常用於記憶體對映io、程序間通訊、讀寫檔案。
flags=map_shared
使用者空間的mmap,在核心中的起點是mmap_pgoff。
#include #include void main(void)
...
mmap(0x20000000, 10240, prot_read, map_private|map_fixed|map_anonymous, -1, 0) = 0x20000000
mmap(0x20000000, 1024, prot_read, map_private|map_fixed|map_anonymous, -1, 0) = 0x20000000
...
如果將第二個mmap的map_fixed去掉呢?結果如下:
...
mmap(0x20000000, 10240, prot_read, map_private|map_fixed|map_anonymous, -1, 0) = 0x20000000
mmap(0x20000000, 1024, prot_read, map_private|map_anonymous, -1, 0) = 0x7fcb336e1000
...
可以看出如果對映區屬性包含map_fixed,則會覆蓋原來區域;如果沒有map_fixed,核心會找到乙個區域。
unsigned long mmap_region(struct file *file, unsigned long addr,
unsigned long len, vm_flags_t vm_flags, unsigned long pgoff)
...}
mmap建立檔案對映時,只建立了vma,而沒有分配對應的頁面和建立對映關係。
2.通過"blockdev --setra"來增大核心預設預讀視窗,預設是128kb。
Linux記憶體管理 9 mmap
專題 linux記憶體管理專題 mmap munmap是常用的乙個系統呼叫,使用場景是 分配記憶體 讀寫大檔案 連線動態庫檔案 多程序間共享記憶體。更詳細解讀參考 linux記憶體管理 9 mmap 補充 mmap munmap函式宣告如下 include void mmap void addr,s...
Linux 記憶體管理之 mmap 解析(二)
1 mmap 系統呼叫形式 void mmap void addr size t len int prot int flags int fd off t offset mmap的作用是對映檔案描述符fd指定檔案的 off,off len 區域至呼叫程序的 addr,addr len 的記憶體區域,如...
Linux記憶體對映 mmap
linux提供了記憶體對映函式mmap,它把檔案內容對映到一段記憶體上 準確說是虛擬記憶體上 通過對這段記憶體的讀取和修改,實現對檔案的讀取和修改,先來看一下mmap的函式宣告 原型 void mmap void addr,size t length,int prot,int flags,int f...