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

Linux- 内存映射文件(Memory-Mapped File)

内存映射文件(Memory-Mapped File)是⼀种将文件内容映射到内存中的机制,允许程序直接访问文件数据,就好像这些数据已经被加载到了内存⼀样。这个机制允许文件的内容被映射到⼀个进程的地址空间,从而允许程序以⼀种更高效的方式读取或写入文件数据,同时,多个进程可以映射同⼀个文件,从而实现进程间的数据共享。这对于进程间通信非常有用。

mmap()

mmap() 是一个Unix和Linux系统调用,用于在进程的地址空间中映射文件或设备,或者创建匿名内存映射。它提供了一种在文件和进程的内存之间建立直接映射的机制。这意味着对于映射的内存区域的任何修改都将直接反映到底层的文件中,反之亦然。

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

以下是 mmap() 函数的基本参数和它们的描述:

  1. 起始地址:

    • 希望映射开始的内存地址。通常设置为 NULL,让系统决定最佳起始地址。
  2. 长度:

    • 要映射的文件或设备的字节数。
  3. 保护:

    • 映射区域的访问权限。常见的权限包括:
      • PROT_READ: 数据可以被读取。
      • PROT_WRITE: 数据可以被写入。
      • PROT_EXEC: 数据可以被执行。
      • PROT_NONE: 数据不能被访问。
  4. 标志:

    • 描述映射的类型和属性。常见的标志包括:
      • MAP_SHARED: 更改会反映到底层文件或其他映射此文件的进程中。
      • MAP_PRIVATE: 创建一个私有的映射,更改不会写回底层文件。
      • MAP_ANONYMOUSMAP_ANON: 创建一个匿名映射,不与任何文件关联。
      • MAP_FIXED: 使用指定的起始地址,如果该地址不可用,映射会失败。
  5. 文件描述符:

    • 要映射的文件或设备的描述符。如果使用 MAP_ANONYMOUS,则此值可以设置为 -1
  6. 偏移:

    • 从文件或设备的哪个位置开始映射。通常,这是以页面大小为单位的,所以通常将偏移量设置为系统页面大小的倍数。

成功调用 mmap() 会返回新映射区域的地址。如果调用失败,则返回 MAP_FAILED,并在 errno 中设置一个错误代码。

几点注意事项:

  • 使用 mmap() 创建的映射应当在不再需要时使用 munmap() 释放。
  • 当映射文件时,文件的长度应该大于或等于要映射的长度。可以使用 ftruncate() 调整文件大小。
  • 写入映射区域超出文件当前大小的部分可能会导致段错误。
  • 对于 MAP_SHARED 映射,更改将写回底层文件,但不一定立即写回。可以使用 msync() 来确保更改被同步到文件。

总的来说,mmap() 是一种强大而灵活的机制,用于文件I/O和进程间通信。

munmap()

munmap() 是一个Unix和POSIX系统调用,用于取消映射一个之前通过 mmap() 映射到进程地址空间的内存区域。映射的内存区域可能是文件的映射、匿名内存或其他类型的内存对象。

当我们不再需要访问一个内存映射或当进程完成其操作并想释放资源时,应该调用 munmap() 来取消映射。

以下是 munmap() 的基本参数和它们的描述:

  1. 地址 (addr):

    • 要取消映射的内存区域的起始地址。这应该是之前 mmap() 调用的返回值。
  2. 长度 (length):

    • 要取消映射的内存区域的长度(以字节为单位)。

函数的基本原型如下:

int munmap(void *addr, size_t length);

返回值:

  • 成功时,munmap() 返回 0
  • 失败时,返回 -1,并设置全局变量 errno 以指示错误原因。

一些常见的使用场景和注意事项:

  • 资源管理:

    • 在不需要访问映射内存区域时,应及时使用 munmap() 释放资源。否则,这可能会导致资源泄漏,尤其是在长时间运行的程序中。
  • 访问已取消映射的内存:

    • 一旦使用 munmap() 取消映射了一个内存区域,任何尝试访问该区域的操作都将导致未定义的行为,通常是段错误 (segmentation fault)。
  • 映射边界:

    • 当取消映射一个内存区域时,必须确保 addrlength 正确地对应于原始 mmap() 调用的值。尝试部分取消映射或使用不正确的地址和长度可能导致错误。
  • 与其他资源的关联:

    • 取消映射并不意味着与该映射相关的其他资源也被释放。例如,如果映射了一个文件,munmap() 只会取消映射,但不会关闭文件。我们仍然需要使用 close() 系统调用来关闭文件。

总的来说,munmap() 是内存映射管理的重要部分,正确地使用它可以帮助避免资源泄漏和确保程序的稳定性。在设计使用内存映射的应用程序时,我们应该始终确保在不再需要映射的时候调用 munmap() 来释放资源。

ftruncate()

ftruncate() 是一个系统调用,用于调整/设置已打开的文件的大小。这个调用可以使文件变大或变小。当文件增大时,新增的部分会被视为“空洞”,并且会读取为零字节;当文件缩小时,超出指定长度的部分将被丢弃。

以下是 ftruncate() 的基本参数和它们的描述:

  1. 文件描述符 (fd):

    • 这是要调整大小的文件的文件描述符。通常,这是使用 open() 或其他相关系统调用获得的。
  2. 长度 (length):

    • 这是要设置的文件的新大小,以字节为单位。

函数的基本原型如下:

int ftruncate(int fd, off_t length);

返回值:

  • 成功时,ftruncate() 返回 0
  • 失败时,返回 -1,并设置全局变量 errno 以指示错误原因。

一些常见的使用场景和注意事项:

  • 内存映射: 在使用 mmap() 创建文件的内存映射之前,如果想映射的部分超过了文件的当前大小,可以使用 ftruncate() 来增加文件的大小。

  • 数据库和日志文件: 数据库系统或日志文件管理系统可能会预先分配大块的磁盘空间以提高效率,而不是每次需要时都增加文件大小。这可以通过 ftruncate() 实现。

  • 文件截断: 如果只想保留文件的前部分并删除其余部分,ftruncate() 可以很容易地做到这一点。

  • 空洞文件: 在某些文件系统上,ftruncate() 可以用于创建所谓的“空洞文件”,这是一个包含未初始化数据(空洞)的文件,这些数据在磁盘上不占用任何空间,但在读取时会返回零字节。

总的来说,ftruncate() 是一个有用的系统调用,尤其是在需要精细控制文件大小或预分配磁盘空间的应用中。

示例

在下面的例子中,我们使用了两个 POSIX 信号量:sem_parent和sem_child来控制两个进程之间的同步。父进程首先写入消息然后通过sem_post通知子进程。子进程在收到消息并处理完后,通过sem_post通知父进程。这种方式确保了两个进程的同步,并且避免了忙等待。

#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <semaphore.h>#define FILE_PATH "shared_memory_file"
#define FILE_SIZE 1024
#define SEM_PARENT "/sem_parent"
#define SEM_CHILD "/sem_child"int main() {int fd;char *shared_mem;// Create a filefd = open(FILE_PATH, O_RDWR | O_CREAT, 0777);if (fd == -1) {perror("open");return 1;}// Set the file sizeftruncate(fd, FILE_SIZE);// Map the file into memoryshared_mem = (char *)mmap(NULL, FILE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);if (shared_mem == MAP_FAILED) {perror("mmap");return 1;}// Create semaphoressem_t *sem_parent = sem_open(SEM_PARENT, O_CREAT, 0666, 0);sem_t *sem_child = sem_open(SEM_CHILD, O_CREAT, 0666, 0);pid_t pid = fork();if (pid == 0) { // Childsem_wait(sem_parent); // Wait for parent signalprintf("[Child] Received: %s\n", shared_mem);// Reply to the parentstrcpy(shared_mem, "Message received by child!");printf("[Child] Replied to parent.\n");sem_post(sem_child); // Signal the parent} else if (pid > 0) { // Parentstrcpy(shared_mem, "Hello from parent!");sem_post(sem_parent); // Signal the child// Wait for child signalsem_wait(sem_child);printf("[Parent] Message from child: %s\n", shared_mem);wait(NULL); // Wait for child to finish} else {perror("fork");return 1;}// Cleanupmunmap(shared_mem, FILE_SIZE);close(fd);unlink(FILE_PATH);sem_close(sem_parent);sem_close(sem_child);sem_unlink(SEM_PARENT);sem_unlink(SEM_CHILD);return 0;
}

程序运行结果如下:

majn@tiger:~/C_Project/mmap_project$ ./mmap_demo 
[Child] Received: Hello from parent!
[Child] Replied to parent.
[Parent] Message from child: Message received by child!

对于超出映射区域的内存访问,结果是不确定的,通常会导致错误。

当尝试访问超出我们通过mmap分配的映射区域的内存地址时,实际上是在访问进程地址空间中的非法地址。这通常会产生一个SIGSEGV信号,该信号表示段违规错误,即“segmentation fault”。

简而言之:

  1. 试图读取超出文件长度但在映射区域内的地址:通常会读到0,这是因为文件被视为以0字节填充直到映射的大小。

  2. 试图访问超出映射区域的地址:通常会导致段违规错误(segmentation fault)。

因此,最好确保只访问映射的内存区域内的地址,避免超出这个范围,以防止未定义的行为和潜在的程序崩溃。

相关文章:

Linux- 内存映射文件(Memory-Mapped File)

内存映射文件&#xff08;Memory-Mapped File&#xff09;是⼀种将文件内容映射到内存中的机制&#xff0c;允许程序直接访问文件数据&#xff0c;就好像这些数据已经被加载到了内存⼀样。这个机制允许文件的内容被映射到⼀个进程的地址空间&#xff0c;从而允许程序以⼀种更高…...

李航老师《统计学习方法》第五章阅读笔记

决策树&#xff08;decision tree&#xff09;是一种基本的分类与回归方法。本章主要讨论用于分类的决策树。决策树模型呈树形结构&#xff0c;在分类问题中&#xff0c;表示基于特征对实例进行分类的过程。 以下是关于分类决策树的一些基本概念和特点&#xff1a; 树形结构&am…...

iOS16新特性:实时活动-在锁屏界面实时更新APP消息 | 京东云技术团队

简介 之前在 《iOS16新特性:灵动岛适配开发与到家业务场景结合的探索实践》 里介绍了iOS16新的特性&#xff1a;实时更新&#xff08;Live Activity&#xff09;中灵动岛的适配流程&#xff0c;但其实除了灵动岛的展示样式&#xff0c;Live Activity还有一种非常实用的应用场景…...

使用 Elasticsearch、OpenAI 和 LangChain 进行语义搜索

在本教程中&#xff0c;我将引导您使用 Elasticsearch、OpenAI、LangChain 和 FastAPI 构建语义搜索服务。 LangChain 是这个领域的新酷孩子。 它是一个旨在帮助你与大型语言模型 (LLM) 交互的库。 LangChain 简化了与 LLMs 相关的许多日常任务&#xff0c;例如从文档中提取文本…...

NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061

今天发现,有两个处理器,启动以后,数据流不过去,后来,锁定问题在,queue队列上面,因为别的队列都可以通过,右键,empty queue清空,就是 这个队列不行,这个队列无法被删除,至于为什么导致这样的, 猜测是因为之前,流程设计好以后,队列没有设置背压,也没有设置队列中的内容大小和fl…...

leetcode20. 有效的括号 [简单题]

题目 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相同类型…...

ubuntu20.04下源码编译colmap

由于稠密重建需要CUDA&#xff0c;因此先安装CUDA&#xff0c;我使用的是3050GPU&#xff0c;nvidia-smi显示最高支持CUDA11.4。 不要用sudo apt安装&#xff0c;版本较低&#xff0c;30系显卡建议安装CUDA11.0以上&#xff0c;这里安装了11.1版本。 下载&#xff1a; cuda_1…...

Jumpserver堡垒机

一、堡垒机概述 1、堡垒机的基本概念 堡垒机也是一台服务器&#xff0c;在一个特定的网络环境下&#xff0c;为了保障网络和数据不受来自外部和内部用户的入侵和破坏&#xff0c;而运用各种技术手段实时收集、监控网络环境中每一个组成部分&#xff08;服务器&#xff09;的系…...

第一百五十三回 如何实现滑动窗口

文章目录 概念介绍实现方法示例代码 我们在上一章回中介绍了自定义组件实现游戏摇杆相关的内容&#xff0c;本章回中将介绍 如何实现滑动窗口.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在本章回中介绍的滑动窗口表示在屏幕底部向上滑动时弹出一个窗口&a…...

Oracle 12c自动化管理特性的新进展:自动备份、自动恢复和自动维护功能的优势|oracle 12c相对oralce 11g的新特性(3)

一、前言: 前面几期讲解了oracle 12c多租户的使用、In-Memory列存储来提高查询性能以及数据库的克隆、全局数据字典和共享数据库资源的使用 今天我们讲讲oracle 12c的另外的一个自动化管理功能新特性:自动备份、自动恢复、自动维护的功能 二、自动备份、自动恢复、自动维护…...

Redis——Jedis中hash类型使用

hset 和 hget hset可以逐一添加key和value&#xff0c;也可以通过map类型来直接添加多组fields 而hget则返回string类型&#xff0c;如果元素不存在则返回null private static void hsetAndHget(Jedis jedis) {jedis.flushAll();jedis.hset("key", "f1"…...

肖sir__项目实战讲解__004

项目实战讲解 一、项目的类型 金融类&#xff1a; 保险(健康险理财险)、证券、基金(股票型基金、混合型基金、指数型基金、债券型基金、 天天基金网&#xff08;ETF基金、货币型基金、量化基金)、银行、贷款、信用卡、外汇、二元期权、期货原油、blockchain、 数字货币、黄金白…...

数据库数据恢复-ORACLE常见故障有哪些?恢复数据的可能性高吗?

ORACLE数据库常见故障&#xff1a; 1、ORACLE数据库无法启动或无法正常工作。 2、ORACLE数据库ASM存储破坏。 3、ORACLE数据库数据文件丢失。 4、ORACLE数据库数据文件部分损坏。 5、ORACLE数据库DUMP文件损坏。 ORACLE数据库数据恢复可能性分析&#xff1a; 1、ORACLE数据库无…...

合规性管理如何帮助产品团队按时交付?

成功的产品和产品发布背后通常需要经过一个涉及多个监督机构、多功能团队和利益相关者的复杂流程。在组织的治理、风险管理和合规性&#xff08;GRC&#xff09;框架下&#xff0c;产品团队不仅需要追求市场创新&#xff0c;还需要确保符合所有适用的法规、标准和合同要求。由于…...

从平均数到排名算法

平均数用更少的数字&#xff0c;概括一组数字。属于概述统计量、集中趋势测度、位置测度。中位数是第二常见的概述统计量。许多情况下比均值更合适。算术平均数是3中毕达哥拉斯平均数之一&#xff0c;另外两种毕达哥拉斯平均数是几何平均数和调和平均数。 算术平均 A M 1 n ∑…...

如何使用ESP8266微控制器和Nextion显示器为Home Assistant展示温度传感器和互联网天气预报

第一部分&#xff1a;引言与项目概述 在智能家居领域&#xff0c;实时监控和显示环境数据已经成为了一个热门的话题。无论是室内温度、室外温度&#xff0c;还是游泳池的温度&#xff0c;都可以通过各种传感器轻松获取。但如何将这些数据以直观、美观的方式展现出来呢&#xf…...

阻塞队列-生产者消费者模型

阻塞队列介绍标准库阻塞队列使用基于阻塞队列的简单生产者消费者模型。实现一个简单型阻塞队列 &#xff08;基于数组实现&#xff09; 阻塞队列介绍 不要和之前学多线程的就绪队列搞混&#xff1b; 阻塞队列&#xff1a;也是一个队列&#xff0c;先进先出。带有特殊的功能 &…...

Vector Art - 矢量艺术

什么是矢量艺术&#xff1f; 矢量图形允许创意人员构建高质量的艺术作品&#xff0c;具有干净的线条和形状&#xff0c;可以缩放到任何大小。探索这种文件格式如何为各种规模的项目提供创造性的机会。 什么是矢量艺术作品? 矢量艺术是由矢量图形组成的艺术。这些图形是基于…...

ruoyi-nbcio增加flowable流程待办消息的提醒,并提供右上角的红字数字提醒(一)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 1、数据库表方面 在原来sys_notice修改基础上增加一个表叫sys_notice_send 表结构如下&#xff1a; DROP …...

数据结构:二叉树的基本概念

文章目录 1. 二叉树的定义2. 二叉树的特点3. 特殊二叉树斜树满二叉树完全二叉树 4. 二叉树的性质 1. 二叉树的定义 如果我们猜一个100以内的数字,该怎么猜才能理论最快呢? 第一种方式:从1,2一直猜到100, 反正数字都是100以内,总能猜到的 第二种方式:先猜50,如果比结果小,猜75…...

利用Socks5代理IP加强跨界电商爬虫的网络安全

随着跨界电商的兴起&#xff0c;爬虫技术在这个领域变得越来越重要。然而&#xff0c;网络安全一直是一个值得关注的问题。在本文中&#xff0c;我们将讨论如何利用代理IP和Socks5代理来增强跨界电商爬虫的网络安全&#xff0c;确保稳定和可靠的数据采集&#xff0c;同时避免封…...

Spring学习笔记6 Bean的实例化方式

Spring学习笔记5 GoF之工厂模式_biubiubiu0706的博客-CSDN博客 Spring为Bean提供了多种实例化方式,通常包括4中(目的:更加灵活) 1.通过构造方法实例化 2.通过简单工厂模式实例化 3.通过factory-bean实例化 4.通过FactoryBean接口实例化 新建模块 spring-005 依赖 <!--S…...

大二毕设.3-网盘系统-用户模块讲解

目录 模块功能介绍 具体实现讲解 constants层&#xff1a;存放用户模块常量类 entity层&#xff1a;存放实体类&#xff0c;与数据库中的属性值基本保持一致 mapper层&#xff1a;对数据库进行数据持久化操作 service层&#xff1a;业务逻辑层&#xff0c;主要是针对具体…...

(Vue2)智慧商城项目

新增两个目录api、utils api接口模块&#xff1a;发送ajax请求的接口模块 utils工具模块&#xff1a;自己封装的一些工具方法模块 第三方组件库vant-ui PC端&#xff1a;element-ui&#xff08;element-plus&#xff09; ant-design-vue 移动端&#xff1a;vant-ui Mint UI…...

Nginx实战

虚拟主机 虚拟主机指的就是⼀个独⽴的站点&#xff0c;具有独⽴的域名&#xff0c;有完整的www服务&#xff0c;例如⽹站、FTP、邮件等 。Nginx⽀持多虚拟主机&#xff0c;在⼀台机器上可以运⾏完全独⽴的多个站点。⼀些草根流量站⻓&#xff0c;常会搭建个⼈站点进⾏资源分享交…...

day-57 代码随想录算法训练营(19)动态规划 part 17

647.回文子串 思路&#xff1a;动态规划 1.dp存储&#xff1a;判断以i开始&#xff0c;j结尾的字符串是否是回文串2.动态转移方程&#xff1a;当s[i]s[j]时&#xff0c;如果j-i<1,d[i][j]true; 如果 dp[i1][j-1]true&#xff0c;那么dp[i][j…...

在项目中,关于前端实现数据可视化的技术选择

前言 在项目中&#xff0c;数据可视化以图表、报表类型为主。 需求背景 技术框架是Vue2.x版本&#xff0c;组件库是Ant Design of Vue能够支撑足够多的图表类型开发图表大小/位置能够随意变动图表样式需要支持丰富多样的用户配置强大、开放的图表语法支持复杂的数据可视化场景…...

DT 卡通材质学习 一

渐变着色器 相交线 笔刷和卡通结合使用 修改器...

【游戏引擎架构】6.2 资源管理器

资源管理器可以分为离线部分系统和运行时系统 文章目录 离线资源管理数据库资产管道 运行时资源管理文件结构内存管理文件间引用 离线资源管理 数据库 UE的数据库可以直接浏览、编辑资产&#xff0c;看到运行时的状态&#xff1b;但也存在两个较大的缺点&#xff1a; 版本管…...

spring的ThreadPoolTaskExecutor装饰器传递调用线程信息给线程池中的线程

概述 需求是想在线程池执行任务的时候&#xff0c;在开始前将调用线程的信息传到子线程中&#xff0c;在子线程完成后&#xff0c;再清除传入的数据。 下面使用了spring的ThreadPoolTaskExecutor来实现这个需求. ThreadPoolTaskExecutor 在jdk中使用的是ThreadPoolExecutor…...

霍山县网站建设公司/软文有哪些

【示例一】回家过春节 原理 使用继承&#xff0c;子类中不需要实现那些重复的订票和庆祝团圆的代码了&#xff0c;避免了代码的重复&#xff1b;子类实现了不同方式的回家方法&#xff0c;把它栓入&#xff08;hook&#xff09;到父类中去&#xff0c;实现了完整的回家过年的逻…...

钓鱼网站到底怎么做/免费建立个人网站

webpack是需要自己编写自己需要的一个配置对象&#xff0c;取决你如何使用webpack,下面指定了所有的可用的配置选项。参考文档&#xff1a;https://doc.webpack-china.org... webapck.config.js var path require(path); #使用Node内置的path模块&#xff0c;并在它前面加上__…...

wordpress图片自动打水印/广告联盟赚钱app

1、用mac系统自带的数码测色计&#xff0c;选RGB模式&#xff0c;将值添加到ColorWithRed:xxx.0/255 最后的alpha选1.0 2、TableView的背景色要用setBackgroundView的方式添加一个空的UIView就可以了&#xff0c;记得UIView autoRelease 3、给TableView赋值的时候&#xff0c;根…...

西昌市做网站的公司/平台推广引流怎么做

1.构建本地拓展的ActionScript库时候要注意SWF文件的版本兼容性&#xff1a; 参考&#xff1a;http://help.adobe.com/zh_CN/air/extensions/WS99209310cacd98cc2d13931c1300f2c84c7-8000.html 2.使用Flash Builder导出用于发行的APk包&#xff1a; 参考&#xff1a;http://hel…...

企业网站排名/seo咨询解决方案

使用情景区别 listenTo用于监听自身意外的对象 on用于监听自身 listenTo和on中的回调函数里的this的区别 listener.listenTo(object, eventName, function(){//此处的this指向listener})object.on(eventName, function(){//此处的this指向object})object.on(eventName, functio…...

建设电子商务网站的试卷/黑帽seo培训多少钱

该标签不是HTML3.2的一部分&#xff0c;并且只支持MSIE3以后内核&#xff0c;所以如果你使用非IE内核浏览器(如&#xff1a;Netscape)可能无法看到下面一些很有意思的效果 该标签是个容器标签 语法&#xff1a;  <marquee></marquee>以下是一个最简单的例子&…...