mmap 可以把磁盘文件的一部分直接映射到内存,这样文件中的位置直接就有对应的内存地址,对文件的读写可以直接用指针来做而不需要read / write 函数。
#include
void *mmap(void *addr, size_t len, int prot, int flag, intfiledes, off_t off);
int munmap(void *addr, size_t len);
返回值:如果mmap 成功则返回映射首地址,如果出错则返回常数MAP_FAILED 。当进程终止时,该进程的映射内存会自动解除,也可以调用munmap解除映射。munmap成功返回0,出错返回-1。
如果addr 参数为NULL ,内核会自己在进程地址空间中选择合适的地址建立映射。如果addr 不是NULL ,则给内核一个提示,应该从什么地址开始映射,内核会选择addr 之上的某个合适的地址开始映射。建立映射后,真正的映射首地址通过返回值可以得到。
len 参数是需要映射的那一部分文件的长度。off 参数是从文件的什么位置开始映射,必须是页大小的整数倍(在32位体系统结构上通常是4K)。filedes是代表该文件的描述符。
prot 参数有四种取值:
PROT_EXEC表示映射的这一段可执行,例如映射共享库
PROT_READ表示映射的这一段可读
PROT_WRITE表示映射的这一段可写
PROT_NONE表示映射的这一段不可访问
flag 参数有很多种取值,这里只讲两种,其它取值可查看mmap(2)
MAP_SHARED多个进程对同一个文件的映射是共享的,一个进程对映射的内存做了修改,另一个进程也会看到这种变化。
MAP_PRIVATE多个进程对同一个文件的映射不是共享的,一个进程对映射的内存做了修改,另一个进程并不会看到这种变化,也不会真的写到文件中去。
下面例子将hello文件映射到内存中去,并改写:
#include
#include
#include
int main(void)
{
int *p;
int fd = open("hello", O_RDWR);
if (fd < 0) {
perror("open hello");
exit(1);
}
p = mmap(NULL, 6, PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) {
perror("mmap");
exit(1);
}
close(fd);
p[0] = 0x30313233;
munmap(p, 6);
return 0;
}
每个字节为8位,即2个16进制数。
当用p[0]=0x30 31 32 33时,低位内存对应文件的开头位置:
33 首地址 文件开头
32
31
30 末地址 文件结尾
所以,文件对应的16进制值为 33 32 31 30
对应的值分别为 3 2 1 0
随后可以用 od -tx1 -tc hello 在 shell 中查看文件的2进制表示
od命令, -t o1,指定 1 字节单位八进制数的对照输出格式
-t d1,指定 1 字节单位十进制数的对照输出格式
-t x1,指定 1 字节单位十六进制数的对照输出格式
-tc, 显示对应的 ASCII字符
阅读(1785) | 评论(0) | 转发(0) |