linux munmap - CSDN
  • munmap执行相反的操作,删除特定地址区域的对象映射。  基 于文件的映射,在mmap和munmap执行过程的任何时刻,被映射文件的st_atime可能被更新。如果st_atime字段在前述的情况下没有得到 更新,首次对映射区的第...
    功能描述: 
    mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。munmap执行相反的操作,删除特定地址区域的对象映射。 

    于文件的映射,在mmap和munmap执行过程的任何时刻,被映射文件的st_atime可能被更新。如果st_atime字段在前述的情况下没有得到
    更新,首次对映射区的第一个页索引时会更新该字段的值。用PROT_WRITE 和 MAP_SHARED标志建立起来的文件映射,其st_ctime
    和 st_mtime
    在对映射区写入之后,但在msync()通过MS_SYNC 和 MS_ASYNC两个标志调用之前会被更新。
    用法:  
    #include 
    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:期望的内存保护标志,不能与文件的打开模式冲突。是以下的某个值,可以通过or运算合理地组合在一起
    PROT_EXEC //页内容可以被执行
    PROT_READ  //页内容可以被读取
    PROT_WRITE //页可以被写入
    PROT_NONE  //页不可访问
    flags:指定映射对象的类型,映射选项和映射页是否可以共享。它的值可以是一个或者多个以下位的组合体
    MAP_FIXED //使用指定的映射起始地址,如果由start和len参数指定的内存区重叠于现存的映射空间,重叠部分将会被丢弃。如果指定的起始地址不可用,操作将会失败。并且起始地址必须落在页的边界上。
    MAP_SHARED //与其它所有映射这个对象的进程共享映射空间。对共享区的写入,相当于输出到文件。直到msync()或者munmap()被调用,文件实际上不会被更新。
    MAP_PRIVATE //建立一个写入时拷贝的私有映射。内存区域的写入不会影响到原文件。这个标志和以上标志是互斥的,只能使用其中一个。
    MAP_DENYWRITE //这个标志被忽略。
    MAP_EXECUTABLE //同上
    MAP_NORESERVE //不要为这个映射保留交换空间。当交换空间被保留,对映射区修改的可能会得到保证。当交换空间不被保留,同时内存不足,对映射区的修改会引起段违例信号。
    MAP_LOCKED //锁定映射区的页面,从而防止页面被交换出内存。
    MAP_GROWSDOWN //用于堆栈,告诉内核VM系统,映射区可以向下扩展。
    MAP_ANONYMOUS //匿名映射,映射区不与任何文件关联。
    MAP_ANON //MAP_ANONYMOUS的别称,不再被使用。
    MAP_FILE //兼容标志,被忽略。
    MAP_32BIT //将映射区放在进程地址空间的低2GB,MAP_FIXED指定时会被忽略。当前这个标志只在x86-64平台上得到支持。
    MAP_POPULATE //为文件映射通过预读的方式准备好页表。随后对映射区的访问不会被页违例阻塞。
    MAP_NONBLOCK //仅和MAP_POPULATE一起使用时才有意义。不执行预读,只为已存在于内存中的页面建立页表入口。
    fd:有效的文件描述词。如果MAP_ANONYMOUS被设定,为了兼容问题,其值应为-1。
    offset:被映射对象内容的起点。
      
        
    返回说明:   
    成功执行时,mmap()返回被映射区的指针,munmap()返回0。失败时,mmap()返回MAP_FAILED[其值为(void *)-1],munmap返回-1。errno被设为以下的某个值   
    EACCES:访问出错
    EAGAIN:文件已被锁定,或者太多的内存已被锁定
    EBADF:fd不是有效的文件描述词
    EINVAL:一个或者多个参数无效
    ENFILE:已达到系统对打开文件的限制
    ENODEV:指定文件所在的文件系统不支持内存映射
    ENOMEM:内存不足,或者进程已超出最大内存映射数量
    EPERM:权能不足,操作不允许
    ETXTBSY:已写的方式打开文件,同时指定MAP_DENYWRITE标志
    SIGSEGV:试着向只读区写入
    SIGBUS:试着访问不属于进程的内存区
    原文地址:
    http://club.cn.yahoo.com/bbs/threadview/1200062866_53__pn1.html


    本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/74012/showart_1091637.html

    ------------------------------

    http://blog.csdn.net/whinah/archive/2007/12/07/1922991.aspx

     

    linux/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 这个区域中的不同部分,这的确提高了一些灵活性,但是……。


    出处:http://www.cnblogs.com/leaven/archive/2011/01/14/1935199.html
    展开全文
  • 内存映射函数mmap, 负责把文件内容或者其他对象映射到进程的虚拟内存空间, 通过对这段内存的读取和修改,来实现对文件的读取和修改,而不需要再调用...munmap执行相反的操作,删除特定地址区域的对象映射。 用法: ...

        内存映射函数mmap, 负责把文件内容或者其他对象映射到进程的虚拟内存空间, 通过对这段内存的读取和修改,来实现对文件的读取和修改,而不需要再调用read,write等操作。文件或者其他对象被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。munmap执行相反的操作,删除特定地址区域的对象映射。
     用法:

    
    
    1. void *mmap(void *start, size_t length, int prot, int flags, 
    2. int fd, off_t offset); 
    3. int munmap(void *start, size_t length);  


     参数:   
     start:映射区的开始地址。
     length:映射区的长度。
     prot:期望的内存保护标志,不能与文件的打开模式冲突。是以下的某个值,可以通过or运算合理地组合在一起

    
    
    1. PROT_EXEC //页内容可以被执行 
    2. PROT_READ  //页内容可以被读取 
    3. PROT_WRITE //页可以被写入 
    4. PROT_NONE  //页不可访问 


        flags:指定映射对象的类型,映射选项和映射页是否可以共享。它的值可以是一个或者多个以下位的组合体
        MAP_FIXED //使用指定的映射起始地址,如果由start和len参数指定的内存区重叠于现存的映射空间,重叠部分将会被丢弃。如果指定的起始地址不可用,操作将会失败。并且起始地址必须落在页的边界上。
       MAP_SHARED //与其它所有映射这个对象的进程共享映射空间。对共享区的写入,相当于输出到文件。直到msync()或者munmap()被调用,文件实际上不会被更新。
        MAP_PRIVATE //建立一个写入时拷贝的私有映射。内存区域的写入不会影响到原文件。这个标志和以上标志是互斥的,只能使用其中一个。
     MAP_DENYWRITE //这个标志被忽略。
     MAP_EXECUTABLE //同上
     MAP_NORESERVE //不要为这个映射保留交换空间。当交换空间被保留,对映射区修改的可能会得到保证。当交换空间不被保留,同时内存不足,对映射区的修改会引起段违例信号。
     MAP_LOCKED //锁定映射区的页面,从而防止页面被交换出内存。
     MAP_GROWSDOWN //用于堆栈,告诉内核VM系统,映射区可以向下扩展。
     MAP_ANONYMOUS //匿名映射,映射区不与任何文件关联。
     MAP_ANON //MAP_ANONYMOUS的别称,不再被使用。
     MAP_FILE //兼容标志,被忽略。
     MAP_32BIT //将映射区放在进程地址空间的低2GB,MAP_FIXED指定时会被忽略。当前这个标志只在x86-64平台上得到支持。
     MAP_POPULATE //为文件映射通过预读的方式准备好页表。随后对映射区的访问不会被页违例阻塞。
     MAP_NONBLOCK //仅和MAP_POPULATE一起使用时才有意义。不执行预读,只为已存在于内存中的页面建立页表入口。
     fd:有效的文件描述词。如果MAP_ANONYMOUS被设定,为了兼容问题,其值应为-1。
     offset:被映射对象内容的起点。

       返回值说明: 
     成功执行时,mmap()返回被映射区的指针。失败时,mmap()返回MAP_FAILED[其值为(void *)-1]。
     

    
    
    1. int   munmap(void *start, size_t length); 

     
     取消参数start所指向的映射内存,参数length表示欲取消的内存大小。
     
     返回值:解除成功返回0,否则返回-1,错误原因存于errno中。
     
     一个简单的实例,实现对framebuffer的操作:

     

    
    
    1. #include <stdio.h>  
    2. #include <sys/mman.h>  
    3. #include <string.h>  
    4. #include <linux/fb.h>  
    5. #include <sys/ioctl.h>  
    6. #include <sys/types.h>  
    7. #include <sys/stat.h>  
    8. #include <fcntl.h>  
    9. #include <stdlib.h>  
    10.  
    11. #ifndef true  
    12.  #define true 1  
    13. #endif  
    14. #ifndef false  
    15.  #define false 0  
    16. #endif  
    17.  
    18.  
    19. int FB_Init()  
    20. {     
    21.     fb = open("/dev/fb0", O_RDWR);  
    22.     if(fb < 0)  
    23.     {  
    24.         fprintf(stderr, "Open Failed\n");  
    25.         return false;  
    26.     }  
    27.       
    28.     if(ioctl(fb, FBIOGET_FSCREENINFO, &f_info) < 0)  
    29.     {  
    30.         fprintf(stderr, "Get FSCREENINFO Failed\n");  
    31.         return false;  
    32.     }  
    33.     if(ioctl(fb, FBIOGET_VSCREENINFO, &v_info) < 0)  
    34.     {  
    35.         fprintf(stderr, "Get VSCREENINFO Failed\n");  
    36.           
    37.         return false;  
    38.     }  
    39.     screen_size = v_info.xres * v_info.yres * (v_info.bits_per_pixel) / 8;  
    40.     fbuffer = mmap(0, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);  
    41.     if((int)fbuffer == -1)  
    42.     {  
    43.         fprintf(stderr, "Mmap error\n");  
    44.         return false;  
    45.     }  
    46. }  
    47. int FB_Close()  
    48. {  
    49.     munmap(fbuffer, screen_size);  
    50.     close(fb);  
    51.     return true;  
    52. }                 
    53. int point(int x,int y, ColorType color)  
    54. {  
    55.     int temp;  
    56.     void *currPoint;  
    57.     if(x < 0 || x >= v_info.width)   
    58.         return false;     
    59.     if(y < 0 || y >= v_info.height)   
    60.         return false;     
    61.     temp = (x + v_info.xoffset) * (v_info.bits_per_pixel/8) +  
    62.                     (y + v_info.yoffset) * f_info.line_length;  
    63.     *((unsigned short *)(fbuffer + temp)) = color;  
    64.     return true;  
    65. }  
    66. int main(int argc, char *argv[])  
    67. {  
    68.     FB_Init();  
    69.     point(100, 100, 0x19ff1d00);  
    70.     FB_Close();  
    71.     return 0;  
    编译运行后就在我们的framebuffer上的坐标为(100, 100)的地方画出一个点。

          本文转自 驿落黄昏 51CTO博客,原文链接:http://blog.51cto.com/yiluohuanghun/857476,如需转载请自行联系原作者



    展开全文
  • 【 mmap/munmap系统调用】 功能描述: mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。munmap执行相反的操作,删除特定...

    【 mmap/munmap系统调用】 

    功能描述: 
    mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。munmap执行相反的操作,删除特定地址区域的对象映射。 
    基 
    于文件的映射,在mmap和munmap执行过程的任何时刻,被映射文件的st_atime可能被更新。如果st_atime字段在前述的情况下没有得到
    更新,首次对映射区的第一个页索引时会更新该字段的值。用PROT_WRITE 和 MAP_SHARED标志建立起来的文件映射,其st_ctime 
    和 st_mtime 
    在对映射区写入之后,但在msync()通过MS_SYNC 和 MS_ASYNC两个标志调用之前会被更新。 
    用法: 
    #include 
    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:期望的内存保护标志,不能与文件的打开模式冲突。是以下的某个值,可以通过or运算合理地组合在一起 
    PROT_EXEC //页内容可以被执行 
    PROT_READ  //页内容可以被读取 
    PROT_WRITE //页可以被写入 
    PROT_NONE  //页不可访问 
    flags:指定映射对象的类型,映射选项和映射页是否可以共享。它的值可以是一个或者多个以下位的组合体 
    MAP_FIXED //使用指定的映射起始地址,如果由start和len参数指定的内存区重叠于现存的映射空间,重叠部分将会被丢弃。如果指定的起始地址不可用,操作将会失败。并且起始地址必须落在页的边界上。 
    MAP_SHARED //与其它所有映射这个对象的进程共享映射空间。对共享区的写入,相当于输出到文件。直到msync()或者munmap()被调用,文件实际上不会被更新。 
    MAP_PRIVATE //建立一个写入时拷贝的私有映射。内存区域的写入不会影响到原文件。这个标志和以上标志是互斥的,只能使用其中一个。 
    MAP_DENYWRITE //这个标志被忽略。 
    MAP_EXECUTABLE //同上 
    MAP_NORESERVE //不要为这个映射保留交换空间。当交换空间被保留,对映射区修改的可能会得到保证。当交换空间不被保留,同时内存不足,对映射区的修改会引起段违例信号。 
    MAP_LOCKED //锁定映射区的页面,从而防止页面被交换出内存。 
    MAP_GROWSDOWN //用于堆栈,告诉内核VM系统,映射区可以向下扩展。 
    MAP_ANONYMOUS //匿名映射,映射区不与任何文件关联。 
    MAP_ANON //MAP_ANONYMOUS的别称,不再被使用。 
    MAP_FILE //兼容标志,被忽略。 
    MAP_32BIT //将映射区放在进程地址空间的低2GB,MAP_FIXED指定时会被忽略。当前这个标志只在x86-64平台上得到支持。 
    MAP_POPULATE //为文件映射通过预读的方式准备好页表。随后对映射区的访问不会被页违例阻塞。 
    MAP_NONBLOCK //仅和MAP_POPULATE一起使用时才有意义。不执行预读,只为已存在于内存中的页面建立页表入口。 
    fd:有效的文件描述词。如果MAP_ANONYMOUS被设定,为了兼容问题,其值应为-1。 
    offset:被映射对象内容的起点。 


    返回说明: 
    成功执行时,mmap()返回被映射区的指针,munmap()返回0。失败时,mmap()返回MAP_FAILED[其值为(void *)-1],munmap返回-1。errno被设为以下的某个值 
    EACCES:访问出错 
    EAGAIN:文件已被锁定,或者太多的内存已被锁定 
    EBADF:fd不是有效的文件描述词 
    EINVAL:一个或者多个参数无效 
    ENFILE:已达到系统对打开文件的限制 
    ENODEV:指定文件所在的文件系统不支持内存映射 
    ENOMEM:内存不足,或者进程已超出最大内存映射数量 
    EPERM:权能不足,操作不允许 
    ETXTBSY:已写的方式打开文件,同时指定MAP_DENYWRITE标志 
    SIGSEGV:试着向只读区写入 
    SIGBUS:试着访问不属于进程的内存区 
    原文地址: 
    http://club.cn.yahoo.com/bbs/threadview/1200062866_53__pn1.html

    展开全文
  • 1.文件映射,能够将硬盘映射到进程的地址,这样可以向操作内存一样来操作文件,而且效率高;但是有一定的限制, · 文件的长度必须大于等于映射的...分别是:mmap和munmap;其函数的原型和所需头文件如下: #include

    1.文件映射,能够将硬盘映射到进程的地址,这样可以向操作内存一样来操作文件,而且效率高;但是有一定的限制,
    · 文件的长度必须大于等于映射的长度;
    · 映射的offset必须是页(page)的整数倍;

    注意:映射不会增长文件的长度;映射部分的内容应该是文件本来就应该有的内容;

    2 .文件映射主要使用到两个函数;分别是:mmap和munmap;其函数的原型和所需头文件如下:

     #include <sys/mman.h>
    
     void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset); 
     参数:addr通常都指定为NULL,让操作系统来决定在内存空间中开辟映射的空间;
         length:为所映射的长度;
         prot:表示protect,该参数描述了映射的所需内存保护;并且不能与文件的开放模式发生冲突)。
         flags: MAP_SHARED才会将内存体现在硬盘, MAP_PRIVATE不会将数据保存到硬盘
         fd:文件描述符
         offset:从文件的哪部分开始映射
    
     int munmap(void *addr, size_t length);
     munmap释放内存中分配的映射内存空间;

    这里写图片描述

                      文件映射示意图

    3 .在当前的目录下面创建(touch)一个文件1.txt,然后使用命令将其文件空间大小改为“文件映射时候的length”大小;当然这里的length大小可以改变,但是值得注意的是当length改变的时候,文件1.txt文件的大小也得跟着改变,不然执行时候,会出现“段错误”;

    改变文件大小方式有两种:

    (1) truncate 1.txt --size=4096
    也可以采用ftruncate,ftruncate和truncate两个函数的功能都相同,只不过ftruncate函数是通过文件的全路径;而truncate是通过文件描述符来达到目的。
    
    (2) dd if=/dev/zero of= 1.txt bs = 1024 count = 4
    /*************************************************************************
        * File Name: mmap.c
        * Author: lixiaogang
        * Mail: 2412799512@qq.com 
        * Created Time: 2017年06月03日 星期六 20时16分31秒
     ************************************************************************/
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<unistd.h>
    #include<sys/mman.h>
    #include<sys/types.h>
    #include<fcntl.h>
    
    int main(int argc,char *argv[])
      {
        int fd = open("1.txt",O_RDWR);
        char buf[] = "hello world.";
        if(fd < 0){
            perror("open");
            return -1;
        }
    
        size_t length = 4096;
        char *ptr =(char*) mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
        if(NULL ==ptr){
            perror("mmap");
            return -1;
        }
        strcpy(ptr,buf);
        munmap(ptr,length);
        close(fd);
    /*注意,这里必须得指定文件1.txt的size大小为      *length=4096的大小,不然会出现段错误;
        //因为mmap内存映射不会像文件读写一样,自动地去增长文件空间的大小
        return 0;
      }
    
    

    打开文件1.txt,此时文件中的内容是

    hello world.

    4 .若将该代码中的MAP_SHARED改为MAP_PRIVATE,则不会将hello wrold写入1.txt文件中,也就是说不会写入到硬盘里面。

    char *ptr =(char*) mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0);
    展开全文
  • munmap执行相反的操作,删除特定地址区域的对象映射。 基 于文件的映射,在mmap和munmap执行过程的任何时刻,被映射文件的st_atime可能被更新。如果st_atime字段在前述的情况下没有得到 更新,首次对映射区的第一...
  • Linux中C库mmap()函数详解》 简介:  Linux的mmap系统调用(libc封装了同名函数)可以分配一段匿名的虚拟内存区域,也可以映射一个文件到内存。  mmap()必须以PAGE_SIZE为单位进行映射,而内存也只能以页为...
  • munmap传入错误参数len,系统不会帮忙校验有效性,而是能删则删,把[addr,addr+len]范围内的进程空间全部移除掉,不管中间是否有空洞。
  • munmap_chunk(): invalid pointer 这是由于free时出现的问题   假如一个结构体如下 typedef struct MSG_HEAD_S { int flag; int a[4]; }msg_head;   msg_head *header = malloc(sizeof(MSG_HEAD_S)); ...
  • 最近的一个C++项目遇到了一个bug,程序会自己退出,...*** glibc detected *** ./a: munmap_chunk(): invalid pointer: 0x000000000c67eb28 *** ======= Backtrace: ========= /lib64/libc.so.6(cfree+0x166)[0x375d272
  • Linux内存管理之mmap详解 一. mmap系统调用 1. mmap系统调用   mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。...
  • IPC三种通信机制是指:信号量、共享内存、消息队列, 信号量:通过操作系统中的PV操作来实现; 共享内存:申请一块内存,进程A往共享内存中写,其他的进程就可以通过读出共享内存中的内容来获取进程A所传送的...
  • munmap 注意事项

    2007-12-07 16:51:00
    linux/unix 下,或者说posix 的munmap,很简单,只有两个参数: int munmap(void *start, size_t length); 其中 length 必须是 mmap 时的 length,如果小于当初 mmap 时的那个 length,并且正好少的部分跨越了一个...
  • sbrk/brk重新指定数据段的结束位置。sbrk(增量),增量可正可负,也可以是0,,都返回原来的数据段结束地址,失败返回-1,。brk(地址),返回0或者-1。头文件。sbrk(0)可以取得当前结束地址。没有使用的虚拟内存地址...
  • mmap、munmap函数

    2019-03-30 21:04:16
    #include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);...int munmap(void *addr, size_t length); void *mmap(void *addr, size_t length, int prot...
  • 一.内存映射文件技术作用 1.使用内存映射文件来访问磁盘上的数据文件。这使你可以不必对文件执行 I / O操作,并且可以不必对文件内容进行缓存. 2.可以使用内存映射文件,使同一台计算机上运行的多个进程能够相互...
  • http://linux.chinaunix.net/techdoc/develop/2008/07/25/1020292.shtml  功能描述: mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一...
  • 头文件:#include #include 定义函数:void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offsize); 函数说明:mmap()用来将某个文件内容映射到内存中,对该内存区域的存取即是直接对...
1 2 3 4 5 ... 20
收藏数 9,205
精华内容 3,682
热门标签
关键字:

linux munmap