mmap与内存管理

原创  mmap与内存管理- mmap系统调用的编程实例 收藏

1        mmap的使用

   mmap地址映射是Linux系统提供的一种功能强大的系统调用,最典型的应用是用于显卡内存的映射。同样,对于普通的硬盘文件也可以进行mmap系统调用。

 

       #include <sys/mman.h>

       void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);

       int munmap(void *start, size_t length);

       参数说明:

       start: 起始虚拟地址,是用户期望使用的虚拟地址,如果进程的虚拟地址空间允许,那么会优先使用该地址。注意:该虚拟地址必须按页尺寸对齐。

       length:映射的长度。

       prot:期望的内存保护,注意不要和打开文件时的属性冲突。属性有PROT_EXECPROT_READPROT_WRITEPROT_NONE,分别为可执行、可读、可写、不可访问。

       flags:指明映像对象的类型。类型有:MAP_FIXED(只使用指定的start虚拟地址)、MAP_SHARED(与其他进程共享该映射)、MAP_PRIVATE(创建一个写拷贝的映射,保持数据不影响原有文件)。

       fd: 打开的文件句柄。

       offset: 指明在文件中的偏移,注意:偏移也必须按页尺寸对齐。

      

    其中最难理解的是start参数,它填入的是程序员期望使用的虚拟地址。如果该虚拟地址不冲突,那么mmap系统调用返回的值就应该是该虚拟地址。

  下面的例子程序就是打开一个普通的文件,对其进行mmap,然后更改其内容。注意:只能更改内容,不能增加文件的长度。

      

 

#include <sys/mman.h>

#include<stdio.h>

#include<unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include<malloc.h>

 

int main()

{

    int fd;

    int i;

    char *p;

 

    fd = open("/mmapDrv",O_RDWR);

    if (fd<0)

    {

        printf("open file  error /n");

        return 0;

    }

  

   /*例子中用户期望的地址是0xb6fff000,注释的mmap语句主要是说明偏移必须是页尺寸的倍数*/

    p=mmap(0xb6fff000,1024, PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

    //p=mmap(0,1024, PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,getpagesize());

    if (p!=NULL)

    {

        printf("mmap ok.p=%x/n",p);

        for (i=0;i<128;i++)

        { 

           sprintf((p+i), "%c",'a');

        }

    }

    getchar() ;

 

    munmap(p,1024);

    close(fd);

    return 0;

}

 

munmap 注意事项

inux/unix 下,或者说posix 的munmap,很简单,只有两个参数:

int munmap(void *start, size_t length);

其中 length 必须是 mmap 时的 length,如果小于当初 mmap 时的那个 length,并且正好少的部分跨越了一个page,那就麻烦了,我就犯了这个错误,非常严重的后果!内存泄漏,不是泄露了刚好少 unmap 的那个 page,而是整个 [start, length) 区域都不会成功被 unmap,也许内存中的更改已经写入文件,但是虚拟内存空间[start,length)未被释放!如此多次,会造成 ENOMEM!

感谢上帝,搞了半天,这个问题终于被发现了。

感觉吧,Windows 的很简单 UnmapViewOfFile 就一个参数,就是 MapViewOfFile 返回的那个地址,UnmapViewOfFile 时整个 map 区域都被释放,而 posix 的 munmap,从理论上讲,可以一次 mmap 一大块区域,然后多次 unmap 这个区域中的不同部分,这的确提高了一些灵活性,但是……。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值