存储映射

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

使用这种方法,首先应通知内核,将一个指定文件映射到存储区域中。这个映射工作可以通过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;
}

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

  1. 共享内存与存储映射(mmap)

    [前言]对这两个理解还是不够深刻,写一篇博客来记录一下. 首先关于共享内存的链接:共享内存.里面包含了创建共享内存区域的函数,以及两个进程怎么挂载共享内存通信,分离.释放共享内存. 共享内存的好处就是 ...

  2. UNIX环境高级编程——存储映射I/O(mmap函数)

         共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共 ...

  3. 高级I/O之存储映射I/O

    存储映射I/O(Memory-mapped I/O)使一个磁盘文件与存储空间中的一个缓冲区相映射.于是当从缓冲区中取数据,就相当于读文件中的相应字节.与此类似,将数据存入缓冲区,则相应字节就自动地写入 ...

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

    存储映射I/O使一个磁盘文件与存储空间中的一个缓冲区相映射,对缓冲区的读.写操作就是对文件的读.写操作,从而能够不再使用read.write系统调用. 将文件映射到存储区的函数由mmap完毕,函数原型 ...

  5. 八、文件IO——存储映射

    8.1 存储映射介绍 8.1.1 概念 存储映射是一个磁盘文件与存储空间的一个缓存相映射,对缓存数据的读写就相应的完成了文件的读写. 文件操作部分映射到虚拟内存的一块区域,我们对虚拟内存映射的那块区域 ...

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

    8. 高级文件操作:存储映射 (1)概念: 存储映射是一个磁盘文件与存储空间的一个缓存相映射,对缓存数据的读写就相应的完成了文件的读写. (2)mmap和munmap函数 头文件 #include&l ...

  7. 存储映射I/O

    一个进程拥有独立并且连续虚拟地址空间,在32位体系结构中进程的地址空间是4G.不过,内核在管理进程的地址空间时是以内存区域为单位.内存区域是进程整个地址空间中一个独立的内存范围,它在内核中使用vm_a ...

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

    内存映射 mmap 内存映射mmap函数的作用是建立一段可以被两个或者多个程度读写的内存段,一个程序对他进行任何修改,对其它程序可见.同样,这个功能可以用在对文件的处理上,mmap函数创建一个指向一个 ...

  9. 深入理解内存映射mmap

    内存映射mmap是Linux内核的一个重要机制,它和虚拟内存管理以及文件IO都有直接的关系,这篇细说一下mmap的一些要点. 修改(2015-11-12):Linux的虚拟内存管理是基于mmap来实现 ...

随机推荐

  1. Leetcode 杂题

    盛最多水的容器   给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) ...

  2. JS基础_for循环练习3

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. Springboot Hikari Centos 首次连数据库很慢

    前言: springboot项目默认使用了hikari作为数据库连接池,在开发机器上一切正常. 但是把程序部署到Centos7 x64上之后发现,每次首页登录的时候都要停顿几十秒. 于是,在程序启动后 ...

  4. Java程序员转行大数据的优势

    大数据时代,中国IT环境也将面临重新洗牌,不仅仅是企业,更是程序员们转型可遇而不可求的机遇. 国内大多数大型互联网公司的程序员被称作研发工程师,但实际上国内几乎没有研发项目,只能叫做开发.开发程序员的 ...

  5. 03 Go语言特性

    一.基本注意事项 1.转义字符 \t 一个制表符,代表一次tab \n 换行符 \\ 转义代表 \ \" 转义代表 " \r 一个回车,从当前行的最前面开始输出,会覆盖以前的内容, ...

  6. Centos7:solr伪集群(SolrCloud)搭建

    JDK,tocmat环境搭建 zookeeper集群安装 解压缩zookeeper的压缩包 创建data目录 复制zoo_sample.cfg为zoo.cfg 修改confg/zoo.cfg中 dat ...

  7. 利用fadeTo改变元素的不透明度代码

    有很多的图片网站中有这样的一种效果:鼠标划过某个元素的时候,与他同级的其他元素的透明度会降低,突出显示这个元素,比如聚美优品的网站就多少用到了这个特效,效果图如下: 不多说,干货代码如下: html部 ...

  8. Linux 永久挂载镜像文件和制作yum源

    Linux mount命令是经常会使用到的命令,它用于挂载Linux系统外的文件. 1.镜像挂载到系统指定目录下:[root@master cdrom]#  mount -t auto  /mnt/c ...

  9. Oracle【三表的联合查询】

    ,'北京','彰显大气'); ,'上海','繁华都市'); ,'广州','凸显舒适'); ,'深圳','年轻气氛'); ,'北上广深','不相信眼泪'); commit; ; ; ; ; ; 员工信息 ...

  10. CentOS 使用 sudo 遇到 command not found 问题解决

    一般通过编译安装的软件会选择自定义路径,例如我编译安装 gvim 在 /usr/loca/bin/ 下,则使用 $ sudo gvim 的时候提示 command not found 问题. 这个问题 ...