void *mmap(void *addr, size_t len, int prot,
int flags,int fildes, off_t off);
- addr:用來告知從哪個記憶體位址開始映射,不過通常是擺 NULL,直接給作業系統決定,否則還要考慮對齊問題(alignment)
- len:映射的大小
- prot:對此記憶體的操作限制,如:PROT_READ、PROT_WRITE、PROT_EXEC、PROT_NONE
- flags:對此記憶體的存取方式,如:MAP_SHARED、MAP_PRIVATE、MAP_FIXED,使用 MAP_SHARED 時,如果某一個行程有對 mmap 的記憶體做修改,那其他同樣有做 mmap 的行程會看到相同結果。(對同一個檔案)
- fildes:open file 所得到的 fd。
- off:指定檔案從哪裡開始對映
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <sys/mman.h> #include <sys/stat.h> #define FILE_LENGTH 0x400 /* 1024 */ int main(int argc, char *argv[]) { int fd; void *map_memory; if(argc < 2) { printf("Usage: ./a.out <string>\n"); return 1; } /* * Open a file to be mapped. * S_IRUSR: read permission, owner * S_IWUSR: write permission, owner */ fd = open("/tmp/shared_file", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); lseek(fd, FILE_LENGTH-1, SEEK_SET); write(fd, "", 1); lseek(fd, 0, SEEK_SET); /* Create map memory. */ map_memory = mmap(0, FILE_LENGTH, PROT_WRITE, MAP_SHARED, fd, 0); close(fd); /* Write to mapped memory. */ if(strlen(argv[1]) < FILE_LENGTH) sprintf((char*)map_memory, "%s", argv[1]); munmap(map_memory, FILE_LENGTH); return 0; }這樣的作法還是可以將內容寫入檔案,而且速度比單純寫入檔案還要快,但似乎 mmap有大小的限制,因為我設定到 0x40000000,程式執行完後,系統變得怪怪的 =.=?。以下是該測試程式的 VMA 區段,位於 /proc/xxxx/maps,其中 xxxx 是 process id,可以在執行程式時輸入 &,如:./mmaptest input_string &。
08048000-08049000 r-xp 00000000 08:06 606289 /home/linly/Sample/mmap_write
...
b7df2000-b7f4a000 r-xp 00000000 08:06 1497227 /lib/tls/i686/cmov/libc-2.8.90.so
...
b7f61000-b7f62000 -w-s 00000000 08:06 686791 /tmp/shared_file
...
b7f80000-b7f81000 rw-p 0001b000 08:06 1479875 /lib/ld-2.8.90.so
bff6c000-bff81000 rw-p bffeb000 00:00 0 [stack]