mmap—存储映射I/O

1.基本概念

存储映射I/O(memory-mapped I/O)能将一个磁盘文件映射到存储空间中的一个缓冲区上。

于是,当从缓冲区中取数据是,就相当于读文件中的相应字节。与此类似,将数据存入缓冲区时,相应字节就自动写入文件。这样就可以在不使用read和write的情况下执行I/O。

为实现该功能,应首先告诉内核将一个给定的文件映射到一个存储区域中。

原理如下:

2.mmap函数完成该功能

 该函数参数较多

首先对于内存而言:

addr参数,用于指定映射存储区的起始地址。通常设置为0(NULL)

我们知道内存地址不能是0地址,也不能3G到4G。

设为0,系统会找一块附近空闲的内存。而该函数的返回值(若成功)即映射区的起始地址。

len参数,申请的字节长度

prot参数,映射区保护要求

flags参数,很重要

        分为MAP_SHARED和MAP_PRIVATE

        共享映射或私有映射

        共享:内存的修改,磁盘也跟着修改磁盘修改,内存也跟着修改。私有则不会,各自为私有数据。

后两个对于磁盘文件而言:

fd,文件描述符

offset,偏移量,以页为单位,4096字节的倍数。

 

 

若返回失败,则返回 MAP_FAILED宏。

失败可能:

内存空间不够

fd文件描述符不存在

或者文件只有读权限,而在内存中去写

注意:

若关闭文件,不会解除映射,

close只是把file结构体的引用计数减1,但映射机制和file结构体没有关系

最后一定要养成良好习惯,申请完要用munmap函数释放,否则会内存泄漏

3.实例

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/mman.h>
#include<stdlib.h>

int main(void){
    int fd,len;
    int *p;
    fd=open("hello",O_RDWR);
    if(fd<0){
        perror("open");
        exit(1);
    }

    len=lseek(fd,0,SEEK_END);//计算长度
    //fstat

    p=mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(p==MAP_FAILED){
        perror("mmap");
        exit(1);
    }
//用的是MAP_SHARED,把内存改了,磁盘文件也会跟着改
    close(fd);
    p[0]=0x30313233;//如果成功,p[0]即索引前四个字节
                    //p指向内存的首地址
                    //对应字符0123

    munmap(p,len);

    return 0;
}

执行程序后,成功把文件修改了。

 

 

4.怎么用mmap实现进程间通信呢?

不难想到,让一个磁盘文件同时映射两个进程。都设置为MAP_SHARED 。

一个进程修改数据,磁盘文件数据修改,然后另一个进程的数据也会修改。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值