了解Linux 的 mmap --- 笔记

news2024/10/7 8:26:09

 学习这篇博客,进行了一些归纳Linux下mmap_linux mmap_一个山里的少年的博客-CSDN博客https://blog.csdn.net/qq_56999918/article/details/127070280

>>读取文件

读取文件方法:由操作系统提供的两个方法,read和write来读写文件。

由于read和write是系统调用,需要先从用户态进入到内核态,再将磁盘中的数据拷贝到操作系统的缓冲区中,然后再将缓冲区中的数据拷贝到用户态中,这个过程进行了两次拷贝。

 >>mmap

① memory map:是一种内存映射文件的方法。

② mmap是一个可以将一个文件或者其他对象映射到进程的地址空间实现磁盘的地址和进程虚拟地址空间一段虚拟地址的一一对应关系。

③ mmap系统调用可以让进程之间通过映射到同一个普通文件实现共享内存,普通文件被映射到进程地址空间当中,之后进程可以向访问普通内存一样对文件进行一系列操作。

【总结】

① 日常中使用read或者write需要进行两次拷贝,一次是将文件拷贝到内核缓冲区,一次是从内核缓冲区拷贝到用户缓冲区。

② 使用mmap可以减少第二次拷贝,由于内核将文件映射到内存,之后用户进程就可以操作这些数据了,用户进程只需要修改内核中的内容,接着通过内核的内存管理器自动将这些数据刷新到磁盘当中。

③ mmap可以提高内存性能,内核空间和用户空间共用一个缓冲区,当多个进程正在对同一个文件进行IO操作,那么通过使用mmap能够共享一个内核缓冲区,从而可以减少内存消耗。

 用户态中的mmap函数以及相关参数详解:

mmap的使用
    #include <sys/mman.h>
    void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
    函数说明:创建虚拟内存到物理内存或者文件的映射
    参数:
        - addr:映射区的起始地址,如果是NULL,系统自动分配
        - length:字节长度自动按照4KB对齐,建议大小一般填成4KB的整数倍
        - prot:映射区域的权限
        - flags:映射的标志位
        - fd:文件描述符
        - offset:文件偏移量自动按照4KB对齐


    prot 的取值:
        PORT_EXEC:映射的区域具有可执行权限
        PROT_READ:映射的区域具有可读权限
        PROT_WRITE:映射区域具有可写权限
        PROT_NONE:映射区域不可被访问
    
    对应flags的取值:
        MAP_SHARED:对映射区域的写入操作直接反映到文件中
        MAP_FIXED:若在start上无法创建映射则失败(如果没有此标记会自动创建)
        MAP_PRIVATE:对映射区域的写入操作只反映到缓冲区当中不会写入到真正的文件
        MAP_ANONYMOUS:匿名映射将虚拟地址映射到物理内存而不是文件(忽略fd)
        MAP_DENYWRITE:拒绝其它文件的写入操作
        MAP_LOCKED:锁定映射区域保证其不被置换
    返回值:函数的返回值为最后文件映射到进程空间的地址,进程可直接操作起始地址为该值的有效地址

 内核态中的mmap函数:

int mmap(struct file* filp,struct vm_area_struct* vma),

>>用户态的mmap函数实现映射到物理内存

#include <iostream>
#include <sys/mman.h>
#include <cstring>
#include <cerrno>
#include <cstdio>
using namespace std;
static const int SIZE = 4096;
int main()
{
    char *str = (char *)mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
    //注意MAP_PRIVATE和MAP_SHARED
    //建立映射
    if (str == MAP_FAILED)
    {
        printf("%s\n", strerror(errno));
        return -2;
    }
    strcpy(str, "hello ksy");
    puts(str);
    //用于取消映射
    munmap(str, SIZE);
 
    return 0;
}

 >>用户态的mmap函数实现映射到文件

#include <iostream>
#include <sys/mman.h>
#include <cstring>
#include <cerrno>
#include <cstdio>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
using namespace std;
static const int SIZE = 4096;
int main()
{
    int fd = open("./a.txt", O_RDWR | O_CREAT, 0644);
    truncate("a.txt", 1024);
    if (fd < 0)
    {
        printf("%s\n", strerror(errno));
        return -1;
    }
    char *str = (char *)mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    //注意MAP_PRIVATE和MAP_SHARED
    //建立映射
    if (str == MAP_FAILED)
    {
        printf("%s\n", strerror(errno));
        close(fd);
        return -2;
    }
    strcpy(str, "helloworld");
    close(fd);
 
    return 0;
}

【注意】

如果不加truncate("a.txt", 1024);会出现总线错误 (核心已转储)

【原因】mmap是虚拟内存映射到文件(物理内存)。由于heheda.txt是新创建的,也就是0个字节。那么在映射时候也是映射了0个字节,这个文件映射过来的内存是没有的,所以我们往里面写东西就会崩溃,truncate函数对文件提前处理一下:

int truncate(const char *path, off_t length);

函数说明:truncate()会将参数path指定的文件大小改为参数length指定的大小。

如果原来的文件大小比参数length大,则超过的部分会被删除。可以提前使用这个函数提前将文件的大小进行设置,就可以向映射的这块内存进行写入了。也就可以成功将其写入到文件中了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/841425.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

eNSP:mgre与ospf的优化综合实验

实验要求&#xff1a; 第一步&#xff1a;路由器、IP的配置 r1: <Huawei>sys Enter system view, return user view with CtrlZ. [Huawei]sys r1 [r1]int g 0/0/0 [r1-GigabitEthernet0/0/0]ip add 172.16.1.1 20 [r1-GigabitEthernet0/0/0]int lo0 [r1-LoopBack0]ip a…

C#,数值计算——堆选择(Heap Select)的计算方法与源程序

1 简述 HeapSelect 是一种用于选择数组中第 K 个最大元素的算法。它是选择问题的变体&#xff0c;涉及在无序或偏序集合中查找特定元素。 算法概要&#xff1a;数组被转换为最大堆&#xff0c;然后反复删除根节点并替换为下一个最大的元素&#xff0c;直到找到第 K 个最大的元…

2023《财富》500强|500强中超过10%已是盖雅客户,100强中已合作超过1/4

7月11日 &#xff0c;财富中文网发布了 &#xff0c;该榜单覆盖范围包括在中国境内外上市的所有中国公司&#xff0c;根据全球范围内最大的中国上市企业过去一年的业绩和成就进行排名。因此&#xff0c;上榜的上市公司不仅是经营规模大&#xff0c;绝大多数也是各自行业的龙头…

【LeetCode】240.搜索二维矩阵Ⅱ

题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,…

【无标题】云原生在工业互联网的落地及好处!

什么是工业互联网&#xff1f; 工业互联网&#xff08;Industrial Internet&#xff09;是新一代信息通信技术与工业经济深度融合的新型基础设施、应用模式和工业生态&#xff0c;通过对人、机、物、系统等的全面连接&#xff0c;构建起覆盖全产业链、全价值链的全新制造和服务…

软件测试工程师的基础必备技能:功能测试解读

什么是功能测试&#xff1f; 根据百科的官方定义&#xff1a;功能测试就是对产品的各功能进行验证&#xff0c;根据功能 测试用例&#xff0c;逐项测试&#xff0c;检查产品是否达到用户要求的功能。 通俗的解读&#xff1a; 功能测试&#xff0c;也叫行为测试&#xff0c;即测…

【mysql】实现递归查询

mysql实现递归查询的方法&#xff1a;首先创建表&#xff0c;并初始化数据&#xff1b;然后向下递归&#xff0c;利用find_in_set()函数和group_concat()函数、with recursive实现递归查询。 mysql实现递归查询的方法&#xff1a; 1、创建表 DROP TABLE IF EXISTS t_areainf…

微信小程序分享实现拉新绑定(用户关系绑定)

分享人此时已经是登陆状态&#xff0c;所以在分享的时候直接从本地存储中拿到用户的userId并拼接到分享链接上&#xff0c;其他用户在点击链接打开详情页之后会判断当前链接参数中有无uid有的话则直接存入本地中用作新用户登录注册时候请求接口的判断&#xff0c;最后在砍价记录…

win10 2022unity设置中文

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言解决方法 前言 在Edit->preferences里找不到language选项。 解决方法 【1】打开下面地址 注意 :把{version}换成你当前安装的版本&#xff0c;比如说如果…

Hive创建外部表详细步骤

① 在hive中执行HDFS命令&#xff1a;创建/data目录 hive命令终端输入&#xff1a; hive> dfs -mkdir -p /data; 或者在linux命令终端输入&#xff1a; hdfs dfs -mkdir -p /data; ② 在hive中执行HDFS命令&#xff1a;上传/emp.txt至HDFS的data目录下&#xff0c;并命名为…

高德地图实现点聚合功能的详细步骤

目录 介绍准备工作1.注册并登录高德地图开放平台&#xff0c;申请密钥2.在Vue项目中安装高德地图的相关库/插件。 一、点聚合1.引入高德地图API<font color purple>initializeMap()<font color purple>loadData()<font color purple>createMarkerClustere…

4 三组例子,用OpenCV玩转图像-AI-python

读取&#xff0c;缩放&#xff0c;旋转&#xff0c;写入图像 首先导入包&#xff0c;为了显示导入matplotlib/为了在matplotlib显示 导入CV2/查看版本 导入图片/查看图片类型 图片数组 数组大小 对于opencv通道顺序蓝色B、绿色G、红色R matplotlib通道顺序为 红色R、绿色G、蓝…

前端架构师岗位的工作职责(合集)

前端架构师岗位的工作职责1 职责&#xff1a; 1.制定前端的标准和规范&#xff0c;并推广和应用&#xff0c;提高团队的开发效率; 2.前端架构的框架或核心模块的设计与实现; 3.在前端架构、设计与开发上对团队进行足够的指导; 4.在日常的系统设计与优化上与服务端团队紧密合…

深度学习基础知识扫盲

深度学习 监督学习&#xff08;Supervised learning&#xff09;监督学习分类 无监督学习&#xff08;Non-supervised learning&#xff09;无监督学习的算法无监督学习使用场景 术语特征值特征向量特征工程&#xff08;Feature engineering&#xff09;特征缩放Sigmod functio…

【果树农药喷洒机器人】Part2:机器人变量喷药系统硬件选型

本专栏介绍&#xff1a;付费专栏&#xff0c;持续更新机器人实战项目&#xff0c;欢迎各位订阅关注。 关注我&#xff0c;带你了解更多关于机器人、嵌入式、人工智能等方面的优质文章&#xff01; 文章目录 一、引言二、变量喷药系统总体要求2.1系统功能要求2.2系统技术要求 三…

怎样能做成小米左侧边栏效果

1、现在我想做成小米左侧边栏这样的效果&#xff0c;该怎么做呢&#xff1f; 2、小米商城触碰之后会显示出新的商品案例 3、一碰到之后会出现这个列表 4、这里涉及到了元素显示模式&#xff1a; 5、用人进行划分可以分为男人和女人&#xff0c;根据男人和女人的特性进行相应的…

JJWT快速入门

本篇介绍使用 JJWT&#xff08;Java JWT&#xff09;库来生成 JWT Token&#xff0c;步骤如下&#xff1a; 添加依赖&#xff1a; 在项目中添加 JJWT 依赖项。对于 Maven 项目&#xff0c;可以在 pom.xml 文件中添加以下依赖项&#xff1a; <dependency><groupId>…

通用FIR滤波器的verilog实现(内有Lowpass、Hilbert参数生成示例)

众所周知&#xff0c;Matlab 中的 Filter Designer 可以直接生成 FIR 滤波器的 verilog 代码&#xff0c;可以方便地生成指定阶数、指定滤波器参数的高通、低通、带通滤波器&#xff0c;生成的 verilog 代码也可以指定输入输出信号的类型和位宽。然而其生成的代码实在算不上美观…

uniapp实现支付宝菜单展开与收起

需求实现支付宝类似的效果&#xff1a; 思路&#xff1a; 1.首先建立展开收起按钮&#xff0c;这里使用的是uview里面的icon图标。 2.其次建立展开菜单内容&#xff0c;这里只演示了文本信息&#xff0c;后期引入首页应用。 3.最后写js逻辑&#xff0c;展开收起时改变盒子高度和…

windows .gitignore 加入文件名后 依然可以从git status中看到文件问题

最近在学git&#xff0c;对着b站的视频操作&#xff0c;结果很简单的添加.gitignore文件操作&#xff0c;up主的正常隐藏&#xff0c;我的却一直出问题。 百思不得其解&#xff0c;网上各种啥啥啥清缓存都没讲到点上。 最后发现是.gitignore文件有问题&#xff0c;windows默认…