了解Linux 的 mmap --- 笔记

这篇具有很好参考价值的文章主要介绍了了解Linux 的 mmap --- 笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

>>读取文件

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

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

了解Linux 的 mmap --- 笔记,linux,运维,服务器

 >>mmap

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

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

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

了解Linux 的 mmap --- 笔记,linux,运维,服务器

【总结】

① 日常中使用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;
}

了解Linux 的 mmap --- 笔记,linux,运维,服务器

 >>用户态的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;
}

了解Linux 的 mmap --- 笔记,linux,运维,服务器

【注意】

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

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

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

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

如果原来的文件大小比参数length大,则超过的部分会被删除。可以提前使用这个函数提前将文件的大小进行设置,就可以向映射的这块内存进行写入了。也就可以成功将其写入到文件中了文章来源地址https://www.toymoban.com/news/detail-628223.html

到了这里,关于了解Linux 的 mmap --- 笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux服务器常见运维性能测试(1)综合跑分unixbench、superbench

    最近需要测试一批服务器的相关硬件性能,以及在常规环境下的硬件运行稳定情况,需要持续拷机测试稳定性。所以找了一些测试用例。本次测试包括在服务器的高低温下性能记录及压力测试,高低电压下性能记录及压力测试,常规环境下CPU满载稳定运行的功率记录。 这个系

    2024年02月04日
    浏览(74)
  • Linux本地部署1Panel服务器运维管理面板并实现公网访问

    1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器,包括主机监控、文件管理、数据库管理、容器管理等 下面我们介绍在Linux 本地安装1Panel 并结合cpolar 内网穿透工具实现远程访问1Panel 管理界面 执行如下命令一键安装 1Panel: 安

    2024年02月04日
    浏览(92)
  • [1Panel]开源,现代化,新一代的 Linux 服务器运维管理面板

    本期测评试用一下1Panel这款面板。1Panel是国内飞致云旗下开源产品。整个界面简洁清爽,后端使用GO开发,前端使用VUE的Element-Plus作为UI框架,整个面板的管理都是基于docker的,想法很先进。官方还提供了视频的使用教程,本期为大家按照本专栏的基本内容进行多方面的测评。

    2024年02月07日
    浏览(89)
  • 华为云云耀云服务器L实例评测 | Linux系统宝塔运维部署H5游戏

    本章节内容,我们主要介绍华为云耀服务器L实例,从云服务的优势讲起,然后讲解华为云耀服务器L实例资源面板如何操作,如何使用宝塔运维服务,如何使用运维工具可视化安装nginx,最后部署一个自研的H5的小游戏(6岁的小朋友玩的很开心😁)。 前端的同学如果想把自己

    2024年02月07日
    浏览(56)
  • Linux服务器常见运维性能测试(3)CPU测试super_pi、sysbench

    最近需要测试一批服务器的相关硬件性能,以及在常规环境下的硬件运行稳定情况,需要持续拷机测试稳定性。所以找了一些测试用例。本次测试包括在服务器的高低温下性能记录及压力测试,高低电压下性能记录及压力测试,常规环境下CPU满载稳定运行的功率记录。 这个系

    2024年02月02日
    浏览(52)
  • 【Linux学习笔记】Linux服务器:配置与管理samba服务器

    一、【linux学习笔记】红帽Linux 7.8系统在虚拟机上的安装 二、【Linux学习笔记】Linux系统的基本操作  三、【Linux学习笔记】管理Linux操作系统:用户管理  四、【Linux学习笔记】管理Linux操作系统:磁盘管理 五、【Linux学习笔记】管理Linux操作系统:软件安装  六、 【Linux学习

    2024年02月02日
    浏览(44)
  • 【Linux】主机搭建 Linux服务器环境 笔记

    过年买了个 mini 主机当玩具玩一下,这里记录下。 已有主力机 (windows) 的情况下,使用过如下四种 Linux宿主环境。这里总结下区别。 优点 云服务器 虚拟机 笔记本电脑 mini主机 价格低 √ √ 便携 √ √ 环境隔离 √ √ √ 详细过程不贴出来了,把关键点回忆一下,方便以后快

    2024年02月21日
    浏览(60)
  • 【阅读笔记】Linux 高性能服务器编程

    原文地址以及最新代码参考:https://github.com/EricPengShuai/Interview/tree/main/Linux Ch.5 Linux 网络编程基础 API 5.1 socket 地址 API 5.1.1 主机字节序和网络字节序 大端字节序(网络字节序):高位低地址 小端字节序(主机字节序):高位高地址 参考代码:5-1byteorder.cpp 一般网络编程中,发

    2024年02月06日
    浏览(47)
  • 《Linux高性能服务器编程》笔记02

    参考 Linux高性能服务器编程源码: https://github.com/raichen/LinuxServerCodes 豆瓣: Linux高性能服务器编程 Linux提供了很多高级的I/O函数。它们并不像Linux基础I/O函数(比如open和read) 那么常用(编写内核模块时一般要实现这些I/O函数),但在特定的条件下却表现出优秀的性 能。本章将讨论

    2024年01月21日
    浏览(54)
  • 《Linux高性能服务器编程》笔记01

    本文是读书笔记,如有侵权,请联系删除。 参考 Linux高性能服务器编程源码: https://github.com/raichen/LinuxServerCodes 豆瓣: Linux高性能服务器编程 □socket地址API。socket最开始的含义是一个IP地址和端口对(ip,port)。它唯一地 表示了使用TCP通信的一端。本书称其为socket地址。 □s

    2024年01月22日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包