mmap 核心優勢
- 高效 I/O:將檔案直接映射到虛擬記憶體,讀寫轉為指標操作,避免
read/write 系統調用與資料拷貝。
- 共享記憶體:多進程映射同一檔案(
MAP_SHARED)實現零拷貝進程間通訊。
- 適用範圍:僅支援可定位檔案(普通檔、塊設備),不支援管道、Socket。
關鍵 API 速查
| 函數 | 用途 | 關鍵參數 |
mmap | 建立映射 | start=NULL 由核心決定位址,prot (PROT_READ|PROT_WRITE),flags (MAP_SHARED/MAP_PRIVATE) |
munmap | 解除映射 | start, length |
mprotect | 修改保護屬性 | PROT_READ/PROT_WRITE/PROT_EXEC |
mremap | 擴大/縮小映射區 | MREMAP_MAYMOVE 允許移動位址 |
完整範例:讀寫檔案內容
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
int main() {
int fd = open("testfile", O_RDWR);
if (fd < 0) { perror("open"); return 1; }
/* 映射整個檔案 */
off_t len = lseek(fd, 0, SEEK_END);
char *map = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED) { perror("mmap"); close(fd); return 1; }
/* 讀取並列印 */
char buf[100];
strcpy(buf, map);
printf("mmap read: %s\n", buf);
/* 修改內容(自動同步回檔案) */
strcpy(map, "Buf Is Not Null!");
printf("mmap write: %s\n", map);
munmap(map, len);
close(fd);
return 0;
}
常見坑點
MAP_PRIVATE 修改不回寫檔案,適合 Copy-on-Write 快照場景。
- 映射長度建議 ≥ 檔案大小;擴充檔案需先
ftruncate 再 mremap。
- 多線程/進程並發修改需自行加鎖(
pthread_mutex 或檔案鎖)。