当前位置: 首页 > news >正文

mmap 虚拟地址映射

mmap允许你将一个文件或设备直接映射到进程的虚拟地址空间,这样进程就能像访问普通内存一样读写文件内容,无需频繁调用 read或 write等 I/O 函数

一.mmap与write/read的区别

对于read/write而言

对于一次文件的操作

  1. 进程调用 read,陷入内核态。

  2. 内核检查请求的文件数据是否在​​页缓存​​中。

  3. 若不在,内核从磁盘读取数据到​​页缓存​​。

  4. 内核将数据从​​页缓存​​拷贝到进程用户空间指定的缓冲区。

  5. 在这个拷贝过程中,CPU通过该进程的​​页表​​,将缓冲区的虚拟地址翻译为物理地址,从而写入数据。

需要经历以上5个操作

而对于mmap而言

它跳过了第4个阶段,也就是节省了拷贝的过程。会直接通过进程页表指向内核态的页缓存。

并且当你把建立虚拟地址映射后,你可以像操作指针一下对文件进行读写

可以看到对于文件的操作,大部分时候使用mmap会效率更高,但是一些大文件顺序读取的时候read/write可能会更优,因为他有缓冲区和预读机制。

二.mmap的使用

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

简单的使用

1.对于flag 为Map_shared就相当于对文件进行映射

1).写

#include <sys/mman.h>
#include <iostream>
#include <unistd.h>
#include <fcntl.h>#define PAGE_SIZE 4096
int main(int argc, char* argv[])
{if(argc != 2){std::cout << "Usage: " << argv[0] << "filename" << std::endl;}//打开文件int fd = ::open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666);//文件扩容--mmap不会对文件扩容::ftruncate(fd, PAGE_SIZE);//映射文件到内存  PAGE_SIZE传入必须要是 页大小的整数倍char* addr = (char*)::mmap(NULL, PAGE_SIZE, PROT_WRITE, MAP_SHARED, fd, 0);//写入数据for(char i = 'a' ; i <= 'z'; i++){addr[i-'a']=i;sleep(1);}//解除映射::munmap(addr, PAGE_SIZE);//关闭文件::close(fd);
}

log文件的每秒变化

2).读

#include <sys/mman.h>
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>#define PAGE_SIZE 4096
int main(int argc, char* argv[])
{if(argc != 2){std::cout << "Usage: " << argv[0] << "filename" << std::endl;}//打开文件int fd = ::open(argv[1], O_RDWR);struct stat st;::fstat(fd, &st);//映射文件到内存  PAGE_SIZE传入必须要是 页大小的整数倍char* addr = (char*)::mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);//读取数据std::cout << "File Content: " << addr << std::endl;//解除映射::munmap(addr, PAGE_SIZE);//关闭文件::close(fd);
}

2.对于flags Map_private就相当于使用创建一块私有内存

对于malloc他的底层对于大块空间的获取,一般使用的就是mmap作为调用

#include <sys/mman.h>
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>void* mmap_alloc(size_t size)
{void* addr = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);return addr;
}
void mmap_free(void* addr, size_t size)
{::munmap(addr, size);
}
int main()
{char* addr = (char*)mmap_alloc(4096);memset(addr, 'A', 4096);std::cout<<std::endl;for(int i = 0; i < 4096; i++){printf("%c", addr[i]);fflush(stdout);sleep(1);}mmap_free(addr, 4096);
}

可以看到在虚拟映射表中多出了新的虚拟映射

http://www.dtcms.com/a/403274.html

相关文章:

  • 网站做好第二年要多少钱wordpress添加文件2m
  • Linux编程笔记2-控制数组指针函数动态内存构造类型Makefile
  • 【数据结构】冒泡、选择、插入、希尔排序的实现
  • npm镜像源配置指南
  • 【QT常用技术讲解】QTreeWidget实现树形筛选框(包含源码)
  • 站长工具ip查询外贸平台实训总结
  • 在JavaScript / HTML中,让<audio>元素中的多个<source>标签连续播放
  • 【Web前端|第二篇】JavaScript对象和事件
  • Linux配置网络————设置虚拟机为静态ip的网络配置详细教程
  • EPGF 架构为什么能保持长效和稳定?
  • reader should realize that all properties of real numbers that are to句子分析
  • ubuntu安装失败:Sorry, there was a problem completing the installation.原因分析及解决办法
  • 深圳商城网站设计价格网站轮播广告
  • AR技术:轨道交通运维与安全保障的革新力量
  • 友元类和友元函数bug
  • Zabbix7.4.8(二):通过http监控Nginx相关指标
  • 厦门 外贸网站访问数据库的网站开发语言
  • Gerkin+Pytest(python)实现自动化(BDD)
  • 动态住宅IP vs. 静态数据中心IP:未来趋势与当前选择
  • 子域名做微信开放平台网站应用芜湖企业100强
  • 很那网站建设做网站哪个公司好
  • Kafka的核心概念
  • Zookeeper 与 Kafka
  • 巴斯勒相机:30 年技术沉淀,重新定义机器视觉效率​
  • 【Kotlin进阶】泛型的高级特性
  • h.265格式的视频在浏览器无法正常播放,使用ffprobe转为h.264
  • sysbench mysql 单表 insert 压测 , 自定义lua测试脚本
  • 石家庄制作网站的公司电商流量平台
  • 二手车网站html模板西宁网站设计
  • 零成本上线动态博客:用 Rin + Cloudflare 部署个人博客的完整指南