• 内存映射mmap的几个api及其使用


    内存映射 mmap
      内存映射mmap函数的作用是建立一段可以被两个或者多个程度读写的内存段,一个程序对他进行任何修改,对其它程序可见。同样,这个功能可以用在对文件的处理上,mmap函数创建一个指向一个内存区域的指针,该内存区域与可以通过一个打开的文件描述符访问的文件的内容相关联。
    一、mmap函数

    1 #include <sys/mman.h>
    2 void *mmap(void *addr,size_t len,int prot,int flags,int filedes,off_t off);

    参数说明:
    1、addr:用来请求使用某个特定的内存地址。如果他取0,结果指针就将自动分配(这是推荐的做法)。否则会降低程序的可移植性,
    因为不同系统的可用地址范围不一样。

    2、len:可以访问的数量,即内存段的大小。
    3、prot:用于设置内存段访问的权限
        PROT_READ:允许读该内存段
        PROT_WRITE:允许写该内存段
        PROT_EXEC:允许执行该内存段
        PROT_NONE:不能访问
    4、flags:控制程序对内存段的改变所造成的影响
        MAP_PRIVATE:内存段私有,对它的修改值对本进程有效
        MAP_SHARED:把对该内存段的修改保存到磁盘文件中
        MAP_FIXED:该内存段必须位于addr指定的地址处
    5、filedes:打开的文件描述符
    6、off:用以改变经共享内存段访问的文件中数据的起始偏移值


    二、msync函数

    1 #include <sys/mman.h>
    2 int msync(void *addr,size_t len,int flags);

    参数说明:
    1、addr:共享内存起始位置
    2、len: 映射的文件的长度
    3、flags:控制执行修改的方式
        MS_ASYNC 采用异步
        MS_SYNC     采用同步
        MS_INVALIDATE 从文件中读回数据

    三、munmap函数—— 释放内存段

    1 #include <sys/mman.h>
    2 int munmap(void *addr,size_t len);

    参数说明:

    1、addr:共享内存起始位置
    2、len: 映射的文件的长度

    API的使用例子:

     1 #include <unistd.h>
     2 #include <stdio.h>
     3 #include <sys/mman.h>
     4 #include <fcntl.h>
     5 #include <stdlib.h>
     6 
     7 typedef struct record
     8 {
     9     int data;
    10     char string[24];
    11 }RECORD;
    12 
    13 #define N (100)
    14 int main()
    15 {
    16     RECORD rec,*mapped;
    17     int i,f;
    18     FILE *fp;
    19     fp = fopen("records.dat","w+");//以写的方式打开一个文件
    20     for(i=0;i<N;i++)
    21     {
    22         rec.data = i;
    23         sprintf(rec.string,"RECORD-%d",i);
    24         fwrite(&rec,sizeof(RECORD),1,fp);//向文件中写一个记录
    25     }
    26     fclose(fp);
    27     ///////////////////////////////////////////////////////////
    28 
    29     f = open("records.dat",O_RDWR);//以读写的方式打开一个文件描述符
    30     mmaped  = (RECORD*)mmap(0,N*sizeof(RECORD),PROT_WRITE|PROT_READ,MAP_SHARED,f,0);//映射
    31     mmaped[43].data = 123;//修改第43个记录的整型部分
    32     sprintf(mmaped[43].string,"RECORD-%d",mmaped[43].data);//修改字符串部分
    33     msync((void*)mmaped,N*sizeof(RECORD),MS_ASYNC);//将修改同步到文件
    34     munmap((void*)mmaped,N*sizeof(RECORD));//释放内存段
    35     close(f);//关闭文件描述符
    36     return 0;
    37 }
  • 相关阅读:
    JavaScript高级程序设计之元素大小
    软件测试面试必备的一些基础理论概念
    golang跨平台编译
    gin shoudBind
    requests
    excelize
    gin获取全部参数
    golang随机数及pipe
    不安全代码只会在使用 /unsafe 编译的情况下出现
    MongoDB 比较运算符 $eq$gt
  • 原文地址:https://www.cnblogs.com/houjun/p/4881090.html
Copyright © 2020-2023  润新知