Linux编程之mmap示例
一、问题背景
Linux下,针对文件读写操作,一般有三个步骤:
1)把文件内容读入到内存中;调用read(系统调用),从内核态读取文件内容到虚拟内存;
2)修改内存中的内容;在用户空间修改内存中的信息;
3)把内存的数据写入到文件中;调用write(系统调用),从用户态将修改后的内容写入到文件;
过程如下图所示:(本文只讨论mmap,关于page cache,请查看:https://www.cnblogs.com/ronnieyuan/p/12377059.html)
显然一次文件的修改操作,我们对文件内容拷贝了两次;
如何优化上述的文件读写操作?如果可以直接在用户空间读写page cache,那么就不需要将文件数据拷贝到用户空间缓存区这个动作了,mmap即可完成;
使用mmap系统调用可以将用户空间的虚拟内存地址与文件进行映射绑定,对映射或的虚拟内存地址进行读写操作,就如同对文件进行读写操作一样。原理图如下所示:
通过上图可以看出,读写文件都需要经过页缓存,所以mmap映射的正是文件的页缓存,而非磁盘中的文件本身。由于mmap映射的是文件的页缓存,所以就涉及到同步的问题,即页缓存会在什么时候把数据同步到磁盘。Linux内核并不会主动把mmap映射的页缓存同步到磁盘,而是需要用户主动触发。同步mmap映射的内存到磁盘有4个时机:1)调用 msync 函数主动进行数据同步(主动);2)调用 munmap 函数对文件进行解除映射关系时(主动);3)进程退出时(被动);4)系统关机时(被动)。备注:下面示例实测不调用munmap也会写回到文件,保险起见还是主动同步数据到文件,详细的还未研究。
二、mmap示例
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>int main(void)
{int fd;fd = open("in.txt", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);if (-1 == fd){return -1;}void *result;result = mmap(0, 1024, \PROT_READ|PROT_WRITE, \MAP_SHARED, \fd, 0);if (result == (void *)-1) {printf("mmap failed: %s\n", strerror(errno));return -1;}close(fd);//映射完可以立即关闭fd,不应该映射及修改strncpy(result, "z", 1);munmap(0, 1024);return 0;
}
三、理论理解
彻底理解mmap()
Page Cache(页缓存)
mmap 内存映射详解
Linux mmap完全剖析
Linux编程之mmap示例相关推荐
- 【Linux】Linux编程之 mmap解析
前言 虚拟内存系统通过将虚拟内存分割为称作虚拟页(Virtual Page,VP)大小固定的块,一般情况下,每个虚拟页的大小默认是4096字节.同样的,物理内存也被分割为物理页(Physical Pa ...
- linux编程之pthread_create函数
linux编程之pthread_create函数UNIX环境创建线程函数, 具体格式: #include<pthread.h> int pthread_create(pthread_t * ...
- linux c 多显卡编程,Linux 编程之GPU计算(转)
08月11日(星期六) Linux 编程之GPU计算(转) 关于brookgpu的简要介绍看下面的链接: 本文翻译了斯坦福大学网站上的关于brookgpu语言的一篇文章,原文在: 关于brookgpu ...
- Linux编程之GCC编译工具实战-夏曹俊-专题视频课程
Linux编程之GCC编译工具实战-6075人已学习 课程介绍 本课程使得学员能够学会在linux中如何编译C/C++程序,使用GCC工具如何编译静态库,动态库,如何配置运行动态库. ...
- Linux编程之epoll
前言 I/O多路复用有很多种实现.在linux上,2.4内核前主要是select和poll,自Linux 2.6内核正式引入epoll以来,epoll已经成为了目前实现高性能网络服务器的必备技术.尽管 ...
- Linux编程之ioctl
在和设备驱动程序通信时,ioctl是很常用的一个调用,常用来配置.查询或者修改设备的配置.反过来说,编写驱动程序时,ioctl也是经常要实现的一个接口,以便应用程序可以方便地控制设备驱动. 应用程序中 ...
- linux编程之mprotect
mprotect: 设置内存访问权限 mmap 的第三个参数指定对内存区域的保护,由标记读.写.执行权限的 PROT_READ.PROT_WRITE 和 PROT_EXEC 按位与操作获得,或者是限制 ...
- linux编程之GDB调试
GDB是一套字符界面的程序集,可以用它在linux上调试C和C++程序,它提供了以下的功能: 1 在程序中设置断点,当程序运行到断点处暂停 2 显示变量的值,可以打印或者监视某个变量,将某个变量的值显 ...
- linux编程之pipe()函数
管道是一种把两个进程之间的标准输入和标准输出连接起来的机制,从而提供一种让多个进程间通信的方法,当进程创建管道时,每次 都需要提供两个文件描述符来操作管道.其中一个对管道进行写操作,另一个对管道进行读 ...
最新文章
- 从现在到未来50年,传感器将如何改变世界?
- java网络编程之TCP通讯
- android 打卡app,日常小打卡app
- 【新星计划】Linux命令行相关指令汇总
- java datainputstream_Java DataInputStream readUnsignedByte()方法
- iOS开发日记4-第三方登录(ShareSDK)
- 【TensorFlow-windows】keras接口——卷积核可视化
- 监控mysql锁定状态_企业实战Mysql不停机维护主从同步
- GAN全套学习笔记/论文
- 【HDU1166】敌兵布阵,线段树练习
- (转)Fabric 1.0 读写集
- OFFICE技术讲座:双层字体引擎的提出
- 怎样做小游戏挖金子(VC,源码4)
- HTML与CSS案例——人物简介
- 离线语音合成使用——科大讯飞or云知音or百度语音
- 新知实验室 TUIKaraoke在线 K 歌
- 中柏平板bios对照表_BIOS详解及中英文对照表
- [CS144] Lab 1: stitching substrings into a byte
- 《“边缘计算+”技术白皮书》发布!
- 初步了解指针------指针的基本概念