mmap/munmap接口是用戶空間的最經常使用的一個系統調用接口,不管是在用戶程序中分配內存、讀寫大文件,連接動態庫文件,仍是多進程間共享內存,均可以看到mmap/munmap的身影。mmap/munmap函數聲明以下:數組
#include <sys/mman.h> 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參數也是一個重要的參數,有以下常見的參數:code
參數fd能夠看出mmap映射是否和文件相關聯,所以Linux內核中映射能夠分爲匿名映射和文件映射。接口
最後根據文件關聯性和映射區域是否共享等屬性,又能夠分爲以下4種,見表2.1。進程
mmap映射類型內存
映射類型 | 映射類型 | |
---|---|---|
私有映射 | 共享映射 | |
匿名映射 | 私有匿名映射-一般用於內存分配 | 共享匿名映射-一般用於進程間共享內存 |
文件映射 | 私有文件映射-一般用於加載動態庫 | 共享文件映射-一般用於內存映射IO,進程間通訊 |
當使用參數fd=-1且flags=MAP_ANONYMOUS | MAP_PRIVATE時,建立的mmap映射是私有匿名映射。私有匿名映射最多見的用途是在glibc分配大塊內存中,當須要的分配的內存大於MMAP_THREASHOLD(128KB)時,glibc會默認使用mmap代替brk來分配內存。同步
當使用參數fd=-1且flags=MAP_ANONYMOUS | MAP_SHARED。在這種狀況下,建立共享匿名映射。共享匿名映射讓相關進程共享一塊內存區域,一般用於父子進程的之間通訊。it
建立共享匿名映射有以下兩種方式:table
(1)fd=-1且flags= MAP_ANONYMOUS|MAP_SHARED。在這種狀況下,do_mmap_pgoff()->mmap()函數最終調用shmem_zero_setup()來打開一個"/dev/zero"特殊的設備文件。多進程
(2)另一個是直接打開"/dev/zero"設備文件,而後使用這個文件句柄來建立mmap。
私有文件映射時flags的標誌位被設置爲MAP_PRIVATE,那麼就會建立私有文件映射。
私有文件映射的最經常使用的場景是加載動態共享庫。
建立文件映射時flags的標誌位被設置爲MAP_SHARED,那麼就會建立共享文件映射。若是prot參數指定了PROT_WRITE,那麼打開文件須要制定O_RDWR標誌位。共享文件映射一般有以下場景:
(1)讀寫文件:
把文件內容映射到進程地址空間,同時對映射的內容作了修改,內核的回寫機制(writeback)最終會把修改的內容同步到磁盤中。
(2)進程間通訊:
進程之間的進程地址空間相互隔離,一個進程不能訪問到另一個進程的地址空間。若是多個進程都同時映射到一個相同的文件,就實現了多進程間的共享內存的通訊。若是一個進程對映射內容作了修改,那麼另外的進程是能夠看到的。