Chinaunix首页 | 论坛 | 博客
  • 博客访问: 254390
  • 博文数量: 53
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-01 10:17
文章分类

全部博文(53)

文章存档

2013年(53)

分类: C/C++

2013-09-07 22:05:45

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) |
给主人留下些什么吧!~~