Linux系统编程之内存映射

概述

        内存映射是操作系统提供的一种机制,使得文件或设备的内容可以直接映射到进程的虚拟地址空间中。这意味着,我们可以像访问数组一样读写文件内容,而不需要显式地调用I/O函数进行数据传输。内存映射适用于多种应用场景,包括但不限于:大文件处理、数据库和缓存、进程间通信、内存映射文件等。

        内存映射的优势主要体现在如下三个方面。

        1、提高性能:减少了从磁盘到用户空间的数据复制过程。

        2、简化编程模型:可以通过指针直接访问文件内容,就像操作普通内存一样。

        3、支持共享内存:多个进程可以共享同一块内存映射区域,实现高效的进程间通信。

mmap和munmap

        mmap函数用于创建一个新的内存映射或扩展现有的映射,以将文件或设备映射到内存中。通过mmap,我们可以直接访问文件内容,就像操作内存一样简单和高效。这种机制特别适用于需要处理大文件、实现进程间通信、或需要频繁读写特定文件部分的应用场景。其函数原型如下。

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

        各个参数和返回值的含义如下。

        addr:建议的映射起始地址,通常设置为NULL,让操作系统自动选择合适的地址。

        length:映射区域的长度,以字节为单位。

        prot:内存保护标志,指定映射区域的访问权限,取值如下。

        (1)PROT_READ:映射区域可以被读取。

        (2)PROT_WRITE:映射区域可以被写入。

        (3)PROT_EXEC:映射区域可以被执行。

        (4)PROT_NONE:映射区域不可访问。

        flags:指定映射类型的标志,取值如下。

        (1)MAP_SHARED:变更会被共享给其他进程,并且会同步更新到文件中。

        (2)MAP_PRIVATE:创建一个私有副本,变更仅对当前进程可见,不会同步回文件。

        (3)MAP_ANONYMOUS:映射匿名内存,不关联任何文件描述符。

        fd:文件描述符。如果使用了MAP_ANONYMOUS标志,则此参数应设为-1。

        offset:文件中的偏移量,指定了映射区域在文件中的起始位置。

        返回值:成功时返回指向映射区域的指针,失败时返回MAP_FAILED,并设置errno为具体的错误原因。

        munmap函数用于解除之前通过mmap建立的内存映射。它会将指定的地址范围从调用进程的地址空间中删除,并释放相应的资源。其函数原型如下。

int munmap(void *addr, size_t length);

        各个参数和返回值的含义如下。

        addr:要解除映射的内存区域的起始地址。

        length:内存区域的长度。

        返回值:成功时返回0,失败时返回-1,并设置errno为具体的错误原因。

实战代码

        下面的实战代码使用内存映射技术来读取并打印一个文件的内容。

        首先,我们通过调用open函数以只读模式打开名为"hope_wisdom.txt"的文件。接着,使用fstat函数获取文件的统计信息,包括文件大小。然后,通过mmap函数将整个文件内容映射到进程的地址空间中,映射区域设置为只读且私有。这就意味着,对映射内容的任何修改都不会反映到原文件上。

        成功映射后,我们直接将映射区域的内容作为字符串打印出来。最后,通过munmap函数解除了文件内容的内存映射,并关闭了文件描述符。

#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>int main()
{int fd = open("hope_wisdom.txt", O_RDONLY);if (fd == -1){printf("open failed\n");return 1;}// 获取文件大小struct stat sb;if (fstat(fd, &sb) == -1){printf("fstat failed\n");close(fd);return 1;}// 映射文件off_t length = sb.st_size;void *pAddr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);if (pAddr == MAP_FAILED){printf("mmap failed\n");close(fd);return 1;}// 打印内容printf("%s", (char *)pAddr);// 解除映射munmap(pAddr, length);close(fd);return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis XML 配置完整示例(含所有核心配置项)

MyBatis XML 配置完整示例&#xff08;含所有核心配置项&#xff09; 1. 完整 mybatis-config.xml 配置文件 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""htt…

Java 程序运行和类路径处理

PS D:\java_test> java .\java\Dog 错误: 找不到或无法加载主类 .\java\Dog 原因: java.lang.ClassNotFoundException: /\java\DogJava 程序运行和类路径处理 问题描述 在运行 Java 程序时&#xff0c;可能会遇到 ClassNotFoundException 错误&#xff0c;这是因为 Java 虚…

7.学习笔记-Maven进阶(P75-P89)-进度(p75-P80)

1.MAVEN-01-分模块开发的意义 &#xff08;一&#xff09;分模块开发意义 模块可以按功能划分&#xff0c;也可以按团队划分&#xff0c;所以把domain的方法抽取出来&#xff0c;进行共享&#xff0c;从而提高开发 的效率。 &#xff08;1&#xff09;分模块开发的意义&#xf…

CUDA编程之Grid、Block、Thread线程模型

一、线程模型:Grid、Block、Thread概念 ‌1. 层级定义‌ ‌Thread(线程)‌ CUDA中最基本的执行单元,对应GPU的单个CUDA核心(SP)。每个线程独立执行核函数指令,拥有独立的寄存器和局部内存空间‌。 ‌Block(线程块)‌ 由多个线程组成(通常为32的倍数),是逻辑上的并…

8. 深入Spring AI:自定义Advisor

1、前言 前面大篇幅介绍了关于Spring AI Advisor机制,并介绍了一些常见的内置的advisor。今天我们来自定义有一个Advisor。 2、快速开始 要自定义一个属于自己的Advisor,其实很自定义一个AOP一样简单。只需遵循以下步骤: 创建一个Advisor类,实现CallAroundAdvisor或Stre…

【C++】继承----下篇

文章目录 前言一、实现一个不能继承的类二、友元与继承三、继承与静态成员四、多继承以及菱形继承问题1.继承模型&#xff1a;2.菱形继承的问题3.虚拟继承解决数据冗余和二义性的原理4.虚拟继承的原理 五、继承的总结和反思1.继承和组合 总结 前言 各位好呀!今天呢我们接着讲继…

五一去荣昌吃卤鹅?基于Java和天地图的寻找荣昌卤鹅店实践

目录 前言 1、卤鹅哥与甲亢哥的爆火事件 2、荣昌卤鹅产业的空间分布 3、使用Java 和天地图进行产业挖掘 一、地名检索简介 1、地名检索功能 2、地名检索API介绍 二、荣昌卤鹅检索实践 1、数据获取流程 2、天地图API请求构建 3、参数构建及调用 4、结果生成及本地保存…

AI数字人:繁荣背后的伦理困境与法律迷局(8/10)

摘要&#xff1a;本文深入剖析 AI 数字人从虚拟走向现实的历程&#xff0c;阐述其融合多技术实现从静态到动态交互的跨越&#xff0c;爆发式应用于各领域带来的商业价值与社会影响&#xff0c;同时直面由此引发的伦理法律挑战&#xff0c;包括身份认同、数据隐私、责任归属及权…

【C++指南】告别C字符串陷阱:如何实现封装string?

&#x1f31f; 各位看官好&#xff0c;我是egoist2023&#xff01; &#x1f30d; 种一棵树最好是十年前&#xff0c;其次是现在&#xff01; &#x1f4ac; 注意&#xff1a;本章节只详讲string中常用接口及实现&#xff0c;有其他需求查阅文档介绍。 &#x1f680; 今天通过了…

头歌实训之索引

&#x1f31f; 各位看官好&#xff0c;我是maomi_9526&#xff01; &#x1f30d; 种一棵树最好是十年前&#xff0c;其次是现在&#xff01; &#x1f680; 今天来学习C语言的相关知识。 &#x1f44d; 如果觉得这篇文章有帮助&#xff0c;欢迎您一键三连&#xff0c;分享给更…

第25周:DenseNet+SE-Net实战

目录 前言 1.准备工作 2.查看数据 3.划分数据集 4.创建模型 5.编译及训练模型 6.结果可视化 7.总结 前言 &#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 1.准备工作 import torch import torch.nn as nn imp…

什么是Maven

Maven的概念 Maven是一个一键式的自动化的构建工具。Maven 是 Apache 软件基金会组织维护的一款自动化构建工具&#xff0c;专注服务于Java 平台的项目构建和依赖管理。Maven 这个单词的本意是&#xff1a;专家&#xff0c;内行。Maven 是目前最流行的自动化构建工具&#xff0…