存储映射--mmap

存储映射

  • 使一个磁盘文件与存储空间中的一个缓冲区相映射。
  • 当从缓冲区中取数据,就相当于读文件中的相应字节。
  • 将数据存入缓冲区,则相应的字节就自动写入文件。

使用这种方法,首先应通知内核,将一个指定文件映射到存储区域中。这个映射工作可以通过mmap函数来实现。不通过IO。直接操作内存,效率更高。

mmap函数

函数原型

#include <sys/mman.h>

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

参数分析

  • addr : 建立映射区的首地址,由Linux内核指定。使用时,直接传递NULL。
  • length : 映射长度。
  • prot: 映射区权限。
    • PROT_READ:只读。
    • PROT_WRITE:只写。
    • PROT_READ | PROT_WRITE:可读可写。
    • 其它参数不常用,参照手册。
  • flags: 标志位参数(常用于设定更新物理区域、设置共享、创建匿名映射区).
    • MAP_SHARED:会将映射区所做的操作反映到物理设备(磁盘)上。
    • MAP_PRIVATE: 映射区所做的修改不会反映到物理设备。
    • MAP_ANON:匿名映射,不需要已存在的文件进行映射。fd传-1,只能用于亲缘进程间。
  • fd: 用来建立映射区的文件描述符。
  • offset: 起点的偏移量,必须是4K的整数倍。因为映射至少一页,比如5000字节的文件,映射内存也是2页大小,不会正好是5000.

Note

使用MAP_SHARED的时候,要注意打开文件的权限>=映射区权限。因为如果文件没有写权限,映射区有写权限,那么映射区是无法写入文件的,这和MAP_SHARED的目的相反。如是MAP_PRIVATE就没有此要求。

另外,文件打开权限起码要是可读的,如果不可读,那么怎么读取数据映射到内存呢?

返回值

  • 成功调用返回映射的地址。
  • 失败时返回MAP_FAILED,即void * (-1)。设置errno.

munmap函数

函数原型:

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

此函数较为简单,释放映射区,首地址为addr,长度为length.

  • 成功的时候返回0.
  • 失败返回-1且置errno。

应用实例

实现进程间的通信,写进程将一份文件映射到内存,并且每秒写入(覆盖写入)不同的字符串,读进程一直去读。

写进程:

struct Person{
      char name[30];
      int num;
  };
int main(int argc, char const* argv[])
{
    //打开文件,作为映射
    int fd = open("memTest2.txt", O_RDWR);
    //int fd = open("memTest2.txt", O_RDWR);
    int length = sizeof(struct Person);
    ftruncate(fd, length);
    printf("fd=%d\n", fd);
    //映射
    struct Person* mem = (struct Person*)mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (mem == MAP_FAILED) {
        perror("mmap err");
        return -1;
    }
    printf("映射区地址:%0x\n", mem);
    int num = 1;
    while (1) {
        mem->num = num++;
        sprintf(mem->name, "I am a Person%03d", mem->num);
        sleep(1);
    }

    //释放
    munmap(mem, length);
    close(fd);
    return 0;
    }

读进程:

struct Person{
      char name[30];
      int num;
  };

  int main(int argc, char const* argv[])
  {
      //打开文件,作为映射
      int fd = open("memTest2.txt", O_RDWR);
      int length = sizeof(struct Person);
      printf("fd=%d\n", fd);
      //映射
      struct Person* mem = (struct Person *)mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
      if(mem == MAP_FAILED)
      {
          perror("mmap err");
          return -1;
      }
      printf("映射区地址:%0x\n", mem);
      while (1) {
          printf("name=%s,num=%d\n", mem->name,mem->num);
          sleep(1);
      }                  

      //释放
      munmap(mem, length);
      close(fd);
      return 0;
  }

原文地址:https://www.cnblogs.com/love-jelly-pig/p/10063442.html

时间: 2024-10-17 17:42:33

存储映射--mmap的相关文章

mmap存储映射IO

mmap,munmap-- #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); int mprotect(void *addr, size_t len, int prot); int msync(void *addr, size_t length, int fla

第3章 文件I/O(7)_高级文件操作:存储映射

8. 高级文件操作:存储映射 (1)概念: 存储映射是一个磁盘文件与存储空间的一个缓存相映射,对缓存数据的读写就相应的完成了文件的读写. (2)mmap和munmap函数 头文件 #include<sys/types.h> #include<sys/mman.h> 函数 void* mmap(void* addr, size_t length, int prot, int flags,                       int fd, off_t offset); int

【Linux编程】存储映射I/O

存储映射I/O使一个磁盘文件与存储空间中的一个缓冲区相映射,对缓冲区的读.写操作就是对文件的读.写操作,从而可以不再使用read.write系统调用. 将文件映射到存储区的函数由mmap完成,函数原型如下: #include <sys/mman.h> /* 成功返回映射区起始地址,出错返回MAP_FAILED */ void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off); 参数说明: addr

存储映射IO

3.6.7.1.mmap函数3.6.7.2.LCD显示和IPC之共享内存3.6.7.3.存储映射IO的特点(1)共享而不是复制,减少内存操作(2)处理大文件时效率高,小文件不划算 总结:存储映射IO其实本质上就是共享内存,和进程间通信的IPC共享内存是一样的,区 别在于: 存储映射IO:是访问设备文件的说法,例如访问LCD设备,我们的进程是一个视频播放器 ,那么他需要将硬盘中的视频数据读取到内存中,然后再把内存中的数据拷贝到LCD驱动 维护的显存中去,之后硬件会自动实现视频的显示:这个是一般的流

存储映射I/O

一个进程拥有独立并且连续虚拟地址空间,在32位体系结构中进程的地址空间是4G.不过,内核在管理进程的地址空间时是以内存区域为单位.内存区域是进程整个地址空间中一个独立的内存范围,它在内核中使用vm_area_struct数据结构来描述.每个内存区域都有自己访问权限以及操作函数,因此进程只能对有效范围的内存地址进行访问. 存储映射I/O是一种基于内存区域的高级I/O操作,它将磁盘文件与进程地址空间中的一个内存区域相映射.当从这段内存中读数据时,就相当于读磁盘文件中的数据,将数据写入这段内存时,则相

八、文件IO——存储映射

8.1 存储映射介绍 8.1.1 概念 存储映射是一个磁盘文件与存储空间的一个缓存相映射,对缓存数据的读写就相应的完成了文件的读写. 文件操作部分映射到虚拟内存的一块区域,我们对虚拟内存映射的那块区域进行读写操作,读写之后,那块区域自动同步到文件当中. 4G空间分布: 共享内存映射区就是文件映射到的内存区. 8.1.2 mmap---建立内存映射 1 #include <unistd.h> 2 #include <sys/mman.h> 3 //mmap(建立内存映射) 4 voi

Linux之共享内存shm和内存映射mmap

一.共享内存shm 1 概念:多个进程的地址空间都映射到同一块物理内存,这样多个进程都能看到这块物理内存,实现进程间通信,而且不需要数据的拷贝,所以速度最快. 二.内存映射mmap 1 前言:先介绍一下普通的读写文件的原理,进程调用read/write系统调用后会陷入内核,内核开始读写文件,假设内核是在读文件,内核先把文件读取到内核缓冲区,然后把内核缓冲区的数据拷贝到用户缓冲区,实际上整个过程拷贝了两次数据,即先从文件到内核缓冲区,再从内核缓冲区到用户缓冲区: 2 概念:把某个文件映射到进程的地

linux 进程间通信——内存共享映射mmap和munmap

IPC三种通信机制是指:信号量.共享内存.消息队列, 信号量:通过操作系统中的PV操作来实现: 共享内存:申请一块内存,进程A往共享内存中写,其他的进程就可以通过读出共享内存中的内容来获取进程A所传送的信息: 消息队列:创建一个消息队列,进程A往队列里面写,那么进程B通过读队列中的容来获取进程A传送的信息. mmap可以把磁盘文件的一部分直接映射到内存,这样文件中的位置直接就有对应的内存地址,对文件的读写可以直接用指针来操做而不需要read/write函数. #include <sys/mman

3Linux内存映射,mmap()函数

 1mmap()依赖的头文件 #include <sys/mman.h> 2函数声明: void *mmap(void *addr, size_t length, intprot, int flags, intfd, off_t offset); int munmap(void *addr, size_t length); 函数说明: mmap可以把磁盘文件的一部分直接映射到内存,这样文件中的位置直接就有对应的内存 地址,对文件的读写可以直接用指针来做而不需要read/write函数. 3