在 Linux 中,mmap 是一个用于内存映射(Memory Mapping)的系统调用,常用于将文件或设备映射到进程的地址空间中,从而实现高效的文件读写操作。mmap 通常与 mmap() 和 munmap() 系统调用一起使用。
一、mmap 的基本用法
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("file.txt", O_RDONLY);
void *addr = mmap(0, 1024, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr == MAP_FAILED) {
perror("mmap failed");
return 1;
}
// 使用 addr 进行读写操作...
munmap(addr, 1024);
close(fd);
return 0;
}
二、mmap 的常见参数
| 参数 | 说明 |
|---|---|
addr |
指向目标内存地址的指针(可选) |
length |
要映射的字节数 |
prot |
保护方式(PROT_READ, PROT_WRITE, PROT_EXEC) |
flags |
映射标志(MAP_SHARED, MAP_PRIVATE, MAP_FIXED, MAP_ANON 等) |
fd |
文件描述符 |
offset |
文件偏移量(可选) |
三、mmap 的常见用途
-
文件映射(File Mapping):
- 将文件映射到进程的内存中,实现高效读写。
- 适用于需要频繁读写文件的场景。
-
设备映射(Device Mapping):
- 将设备(如字符设备、块设备)映射到内存,用于设备驱动开发。
-
共享内存(Shared Memory):
- 通过
MAP_SHARED实现进程间共享内存。
- 通过
-
匿名内存映射(Anonymous Mapping):
- 使用
MAP_ANON与mmap(0, size, PROT_READ, MAP_SHARED, -1, 0)一起使用,用于创建匿名内存块。
- 使用
四、mmap 的注意事项
- 内存保护:
prot参数决定了内存的保护方式。 - 映射方式:
MAP_SHARED与MAP_PRIVATE的区别在于,MAP_SHARED是共享的,而MAP_PRIVATE是私有的。 - 内存映射范围:
mmap会将文件的一部分映射到内存,offset可用于指定起始位置。 - 内存释放:使用
munmap释放映射的内存。
五、示例:使用 mmap 读取文件
# 读取文件内容并映射到内存
cat file.txt | xargs -I{} sh -c 'echo "{}"' | mmap -f file.txt
或者使用 C 语言实现:
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("file.txt", O_RDONLY);
void *addr = mmap(0, 1024, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr == MAP_FAILED) {
perror("mmap failed");
return 1;
}
char buffer[1024];
read(fd, buffer, 1024);
printf("Read: %sn", buffer);
munmap(addr, 1024);
close(fd);
return 0;
}
六、mmap 的替代方案
read()和write():适用于简单读写,但效率较低。pread()和pwrite():支持文件偏移量,效率更高。fread()和fwrite():适用于结构化数据读写。iovec:适用于多块数据读写,效率更高。
七、总结
mmap是 Linux 中实现内存映射的核心系统调用。- 它可以用于文件、设备、共享内存等场景。
- 使用
mmap可以提高文件读写效率,减少 I/O 开销。
如需进一步了解 mmap 的高级用法(如 MAP_SHARED、MAP_ANON 等),欢迎继续提问。

