淘宝分布式文件存储系统( 三 ) -TFS

淘宝分布式文件存储系统( 三 ) ->>TFS

目录 :
  • 文件重新映射的接口介绍
  • 文件映射 mmap_file.cpp的实现
  • 进行测试
文件重新映射 (增加 或者 减少 文件映射区域的大小)

mremap() 函数的原型如下

#include <sys/mman.h>

void *mremap( void * old_address , size_t old_size , size_t new_size , int flags );

参数说明 :

  • old_address:指向原映射区域的起始地址。
  • old_size:原映射区域的大小,以字节为单位。
  • new_size:新映射区域的大小,以字节为单位。
  • flags:标志参数,用于指定映射操作的行为。常用的标志是 MREMAP_MAYMOVE,表示允许系统将映射区域移动到新的位置。

返回值 :

  • 成功时,返回新映射区域的起始地址。
  • 失败时,返回 MAP_FAILED,并设置 errno 错误码来指示具体错误。
    注意 :
    在使用 mremap() 函数前,需要通过 mmap() 函数创建原始的内存映射区域,并确保该内存映射区域是有效的。另外,mremap() 函数只能用于修改已存在的内存映射区域,无法在不同的文件描述符之间创建新的映射。
文件映射 mmap_file.cpp的实现 :
#include"mmap_file.h"
#include<stdio.h>int static Debug=1 ; namespace qiniu
{namespace largefile{//构造函数MMapFile::MMapFile():size_(0),fd_(-1),data_(NULL){}MMapFile::MMapFile(const int fd):size_(0),fd_(fd),data_(NULL){}MMapFile::MMapFile(const MMapOption& mmp_option, const int fd):size_(0),fd_(fd),data_(0){mmap_file_option_.max_mmap_size_=mmp_option.max_mmap_size_;mmap_file_option_.frist_mmap_size_=mmp_option.frist_mmap_size_;mmap_file_option_.pri_mmap_size_=mmp_option.pri_mmap_size_;}//析构函数MMapFile::~MMapFile(){if(data_){   //映射内容不为空,说明映射成功if(Debug)   printf("file information size : %d ,fd : %d , data : %p\n",size_,fd_,data_);msync(data_, size_, MS_SYNC);      //当我们的数据发生改变,同步信号,更新完成后一起返回//解除文件映射munmap(data_ , size_ );size_=0;fd_=-1;data_=NULL;mmap_file_option_.max_mmap_size_=0;mmap_file_option_.frist_mmap_size_=0;mmap_file_option_.pri_mmap_size_=0;}}//同步文件		bool MMapFile::sync_file()   {if(data_!=NULL && size_>0){  //如果data_为空,或者 映射的大小<0 ,则说明没有映射if( msync(data_ , size_ , MS_SYNC)<0){  //同步失败fprintf( stderr, "file sync falied %s \n", strerror(errno));return false;}return true;}return false;}//文件映射		bool MMapFile::map_file(const bool write)  {int flags=PROT_READ;if(write){flags |= PROT_WRITE;     //同时设置为可读}if(fd_ < 0){        return false ;}if(size_ > mmap_file_option_.max_mmap_size_){  //如果初始化的大小,比我们设定的最大的映射大小还要大size_=mmap_file_option_.max_mmap_size_;  }if(size_< mmap_file_option_.frist_mmap_size_){ //如果size_ 的大小,小于我们第一次分配的大小size_=mmap_file_option_.frist_mmap_size_ ;}if(!ensure_flie_size(size_)){        //调整大小fprintf(stderr , "ensure_flie_size falied: %d\n", size_);return false;}data_=mmap(NULL, size_  , flags, MAP_SHARED , fd_ , 0);  //文件映射if( MAP_FAILED==data_ ){   //内存映射失败,返回 MAP_FAILEDfprintf(stderr, "file failed :%s\n",strerror(errno));fd_=-1;data_=NULL;size_=0;return false;}if(Debug){printf("file map succeed  : size_ : %d ,fd : %d , data : %p\n",size_,fd_,data_);}return true;}//获取映射内存的首地址		void* MMapFile::get_data()const{return data_;     //返回映射内存的起始地址}//获取映射内存的大小		int32_t MMapFile::get_size()const{return size_;    //返回映射内存的大小}bool MMapFile::munmap_file()  {if(munmap(data_ , size_)==-1){    //解除文件映射失败fprintf(stderr , "remove file map falied :%s \n",strerror(errno));return false;}return true;}//解除映射		bool MMapFile::ensure_flie_size(const int32_t size){struct stat s;         //存放文件状态(这个是系统提供的)if(fstat(fd_ , &s) < 0 ){					//获取文件状态fprintf(stderr , "fstat falied :%s \n",strerror(errno));return false;}if(s.st_size<size){        //设置文件大小int res=ftruncate(fd_ , size); //对大小进行调整  if(res<0){             //在 linux系统中,大多数情况返回值<0 表示失败fprintf(stderr , "resize failed :%s \n",strerror(errno));return false;}}return true;}/*重新执行映射  (追加,减少内存)mremap()*///重新映射bool MMapFile::remap_file()    {	//防御性编程if(data_==NULL || size_<0 || fd_< 0){//判断是否存在映射区域fprintf(stderr, "not map file\n");return false;}if(size_==mmap_file_option_.max_mmap_size_){//当前映射区域的大小,已经达到我们设置的最大值fprintf(stderr,"size is already max\n");return false;}int32_t new_size=size_+mmap_file_option_.pri_mmap_size_;   //新的映射区域的大小if(new_size>mmap_file_option_.max_mmap_size_){//如果新的大小大于我们的最大值new_size=mmap_file_option_.max_mmap_size_;}//调整文件大小if(!ensure_flie_size(new_size)){        //调整大小fprintf(stderr , "ensure_flie_size falied: %d\n", size_);return false;}if(Debug)  printf("file map succeed  : %d ,fd : %d , data : %p\n",size_,fd_,data_);//最后进行重新映射void *new_data=mremap(data_ , size_ , size_+ mmap_file_option_.pri_mmap_size_,MREMAP_MAYMOVE);//调整映射区域if(new_data==MAP_FAILED){fprintf(stderr , "remap_file failed :%s \n",strerror(errno));return false;}//赋值data_=new_data;size_=new_size;return true;}}
}
  • 补充:
    这里呢,给大家分享一些方法,当我们在写一些大型项目的时候,我们一般会将标准化的头文件,函数调用需要的头文件,放到一个 .h的文件中,我这里演示的也是这样操作的 :
#ifndef _COMMON_H_
#define _COMMON_H_#include<iostream>
#include<fcntl.h>     
#include<sys/stat.h>
#include<string>
#include<sys/types.h>
#include<stdint.h>
#include <errno.h>
#include<string.h>
#include<stdio.h>
#include <error.h>
#include<sys/mman.h>#endif  /*_COMMON_H_*/     //这样注释起来更加清晰 , 因为我们可能不止包含一个

技巧提示:
如果不知道,我们所写的函数需要什么头文件 ,可以这样操作 man APi

演示 :
man mmap
在这里插入图片描述

对代码的可行性进行测试 :

提示: 整个测试我们需要综合我的上一篇内容, 结合 mmap_file.h 头文件一起 .

#include"mmap_file.h"
#include"common.h"using namespace std;
using namespace qiniu;static const mode_t OPEN_MODE=0644;       //文件的权限
const static largefile::MMapOption mmp_option={10240000,4096 ,4096};  //设置内存映射参数int open_file(string file_name, int open_flags)
{    //OPEN_MODE   如果文件不存在,则创建int fd=open( file_name.c_str(), open_flags, OPEN_MODE); //成功返回值一定>0if( fd<0 ){return -errno;}return fd;
}int main(){const char* file_name="./mapfile_test.txt";//打开一个文件,获取文件的句柄int fd=open_file(file_name , O_RDWR | O_CREAT | O_LARGEFILE );if( fd <0 ){     //返回的文件句柄不合法fprintf(stderr ," open file failed : %s  error desc : %s\n",file_name , strerror(-fd));return -1;}printf("%d\n",fd);largefile::MMapFile *map_file=new largefile::MMapFile(mmp_option,fd);bool is_mmap=map_file->map_file(true);                        //文件映射到内存//printf("文件映射的起始地址: %p\n", map_file->get_data());//printf("映射内存的大小 : %d\n", map_file->get_size());printf(" is_mmap: %d\n",is_mmap);if(is_mmap){memset(map_file->get_data(),'8',map_file->get_size());    //将映射的内存全部置为'8'map_file->sync_file();                                    //同步文件//解除映射map_file->munmap_file();}else{fprintf(stderr,"map file failed \n");}close(fd);	return 0;
}

测试结果:

size: 文件映射到内存的大小。

data: 文件映射到内存的起始地址。

fd: 文件的句柄。
在这里插入图片描述
对测试结果进行说明:

  • 测试程序成功将文件映射到内存,然后将文件映射到内存的起始地址映射的大小文件的句柄,打印了出来。当我们对文件mapfile_test.txt进行查看的时候,文件的内容全是8,说明,映射内存的改变,会同时导致我们源文件的改变(t同步的,当然我们也可以对其进行设置,文件只是共享,映射内存改变不会影响到我们的源文件)。
  • 文件映射大概就是这样 , 后续我会给大家介绍 文件映射操作的实战,还会讲一些大神级别的写法 .

最后给大家分享一个liunx函数帮助文档:
函数帮助文档
*提取码: * 0307

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

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

相关文章

阿里测开面试大全(一)附答案完整版

万字长文&#xff0c;建议收藏 1 什么是POM&#xff0c;为什么要使用它&#xff1f; POM是Page Object Model的简称&#xff0c;它是一种设计思想&#xff0c;而不是框架。大概的意思是&#xff0c;把一个一个页面&#xff0c;当做一个对象&#xff0c;页面的元素和元素之间操…

JS Ajax 封装

ajax 封装 一、 什么是Ajax&#xff1f;二、 Ajax的优缺点&#xff1f;2.1 优点2.2 缺点 三、 Ajax的使用3.1 状态码3.2 xhr的基本使用3.3 ajax原生封装&#xff1a;3.3.1 触发GET请求&#xff1a;3.3.2 调用POST请求&#xff1a; 四、Ajax的约束 一、 什么是Ajax&#xff1f; …

【新版】系统架构设计师 - 案例分析 - 数据库设计

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 案例分析 - 数据库设计数据库基础数据库设计概述E-R模型概念结构设计逻辑结构设计规范化&#xff08;范式&#xff09;反规范化技术数据库事务并发控制索引视图物化视图存储过程触发器数据库性能优…

【Spring Cloud系列】Feign详解与实战

Feign详解与实战 文章目录 Feign详解与实战一、概述二、什么是Feign三、Feign特性四、Feign简单使用3.1 Feign使用步骤3.2 Feign具体使用1. 引入依赖2. 启动类上添加注解3.编写FeignClient接口 五、使用Feign发起http请求5.1 Maven导入Feign配置&#xff0c;并集成Jackson5.2 F…

基于matlab实现的光折射反射(不同界面)程序

完整程序: %平面电磁波在不同介质界面上入射、反射、折射仿真 %ReadMe!!!在下述说明的用户输入区内输入入射角和两介质折射率&#xff0c; %输出反射折射示意图与反射折射系数随入射角变化的曲线 %—————————————————————————————————————…

百度SEO优化TDK介绍(分析下降原因并总结百度优化SEO策略)

TDK是SEO优化中很重要的部分&#xff0c;包括标题&#xff08;Title&#xff09;、描述&#xff08;Description&#xff09;和关键词&#xff08;Keyword&#xff09;&#xff0c;为百度提供网页内容信息。其中标题是最重要的&#xff0c;应尽量突出关键词&#xff0c;同时描述…

9.20 QT作业

widget.h #include <QPainter> //画家 #include <QTimerEvent> #include <QTime> #include<QTimer> //定时器类QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widge…

性能测试之使用Jemeter对HTTP接口压测

我们不应该仅仅局限于某一种工具&#xff0c;性能测试能使用的工具非常多&#xff0c;选择适合的就是最好的。笔者已经使用Loadrunner进行多年的项目性能测试实战经验&#xff0c;也算略有小成&#xff0c;任何性能测试&#xff08;如压力测试、负载测试、疲劳强度测试等&#…

SAP DN已发货但是需求还挂在MD04上的异常处理(SE38执行程序:ATP_VBBE_CONSISTENCY OR SDRQCR21)

背景&#xff1a;DN 80074061已经发完货&#xff0c;但是在MD04上还挂着它的需求 处理方法&#xff1a; HANA S4 版本&#xff0c; SE38 执行程序 ATP_VBBE_CONSISTENCY HANA之前的版本执行程序 SDRQCR21 以 ATP_VBBE_CONSISTENCY 为例&#xff0c;先选择模拟模式 执行&…

【计算机网络】 拥塞控制

文章目录 背景TCP的四种拥塞控制算法慢开始与拥塞避免&#xff1a;快重传&#xff1a;快恢复&#xff1a; 流量控制和拥塞控制本质上的 区别 背景 网络中的链路容量和交换节点中的缓存和处理机都有着工作的极限&#xff0c;当网络的需求超过他们的工作极限时&#xff0c;就出现…

Unity——对象池

对象池是一种朴素的优化思想。在遇到需要大量创建和销毁同类物体的情景时&#xff0c;可以考虑使用对象池技术优化游戏性能。 一、为什么要使用对象池 在很多类型的游戏中都会创建和销毁大量同样类型的物体。例如&#xff0c;飞行射击游戏中有大量子弹&#xff0c;某些动作游戏…

函数扩展之——内存函数

前言&#xff1a;小伙伴们又见面啦。 本篇文章&#xff0c;我们将讲解C语言中比较重要且常用的内存函数&#xff0c;并尝试模拟实现它们的功能。 让我们一起来学习叭。 目录 一.什么是内存函数 二.内存函数有哪些 1.memcpy &#xff08;1&#xff09;库函数memcpy &…

高云FPGA系列教程(9):cmd-parser串口命令解析器移植

文章目录 [toc]cmd-parser库简介cmd-parser库源码获取GW1NSR-4C移植cmd-parser实际测试cmd-parse命令解析器优化 本文是高云FPGA系列教程的第9篇文章。 上一篇文章介绍片上ARM Cortex-M3硬核处理器串口外设的使用&#xff0c;演示轮询方式和中断方式接收串口数据&#xff0c;并…

GLTF编辑器如何快速重置模型原点

1、什么是模型原点&#xff1f; 模型原点是三维建模中的概念&#xff0c;它是指在一个虚拟三维空间中确定的参考点。模型原点通常位于模型的几何中心或基本组件的中心位置。如图所示&#xff1a; 可以看到模型的原点在模型的几何中心 2、模型原点的作用 知道了什么是模型原点&…

可转债实战与案例分析——成功的和失败的可转债投资案例、教训与经验分享

实战与案例分析——投资案例研究 股票量化程序化自动交易接口 一、成功的可转债投资案例 成功的可转债投资案例提供了有价值的经验教训&#xff0c;以下是一个典型的成功案例&#xff1a; 案例&#xff1a;投资者B的成功可转债投资 投资者B是一位懂得风险管理的投资者&#…

idea如何关闭项目文件显示的浏览器图标

这里写自定义目录标题 1.idea经常项目文件右上角弹出图标2.setting中Tools 取消勾选浏览器 1.idea经常项目文件右上角弹出图标 2.setting中Tools 取消勾选浏览器

Zabbix

Zabbix简介 ●zabbix 是一个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 ●zabbix 能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 ●zabbix 由 2 部…

创造您梦寐以求的家居设计——Live Home 3D Pro for Mac

您是否曾经想象过在舒适的家中展现自己独特的风格&#xff1f;现在&#xff0c;您可以通过Live Home 3D Pro for Mac来实现您的家居设计梦想&#xff01;这款强大的3D家居设计软件将带给您无限的创作可能性。 Live Home 3D Pro for Mac是一款专业级的家居设计软件&#xff0c;…

Visual Studio 更新:远程文件管理器

Visual Studio 中的远程文件管理器可以用来访问远程机器上的文件和文件夹&#xff0c;通过 Visual Studio 自带的连接管理器&#xff0c;可以实现不离开开发环境直接访问远程系统&#xff0c;这确实十分方便。 自从此功能发布以来&#xff0c;VS 开发团队努力工作&#xff0c;…

基于STC15单片机电子时钟液晶1602串口显示-proteus仿真-源程序

一、系统方案 1、本设计采用STC15单片机作为主控器。 2、液晶1602显示电子时钟。 3、串口显示电子时钟。 4、按键控制开启暂停清零。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 uint count0; uint8 strPhoto[8]; uint wendu0;P3M0 0x…