博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux C 文件内存映射
阅读量:4162 次
发布时间:2019-05-26

本文共 3342 字,大约阅读时间需要 11 分钟。

这次再次讨论文件的操作,只是对象换成了大型文件。

之所以讨论大型文件,是因为无论当今的热点“大数据处理”,还是老牌的搜索引擎,都会涉及到大型文件的处理效率。

比如前一张我们生成了50000行的日志,那么如果是300万行,甚至更多的时候,我们前一张提到的函数是否还能达到我们能够接受的效率呢。

统计日志行数,分别用LinuxAPI, C标准库实现,可以看到直接调用API,耗时72秒,用C标准库用时20,因为标准库使用了缓存,所以速度上快了三倍。

当我们换成最后一种方法的时候,文件内存映射,速度再次提高了一个级别,不到1秒。相当惊艳的成绩。

 

头文件:<sys/mman.h>

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

第一个参数addr,表示自己制定的映射后的内存地址,一般不指定,除非你想制定确定的内存地址。

第二个参数,内存映射的大小,这里传入的是文件的大小,因为文件不是很大,所以全部大小,如果文件太大,可以分次分批映射。

第三个参数代表权限,PROT_READ/ PROT_WRITE/ PROT_EXEC

第四个参数flag, 代表映射的方式,MAP_PRIVATE / MAP_SHARED 这个参数主要是多个进程映射时使用,主要是对写入进行保护。PRIVATE代表自己又自己的备份。

最后一个参数代表文件的便宜,和第二个参数搭配使用可以分阶段映射大文件。

 

文件映射之所以快,是因为采用了系统中的虚拟内存技术。我们的内存一般都比硬盘小,当内存不足的时候,系统会使用硬盘来做交换分区,对页进行换入换出。虚拟内存既然可以使用硬盘来作为内存的备份,这就为文件映射提供了很好的实现方式。只需要把文件本身当作我们的交换分区,那么随时通过交换分区的算法(页中断算法)靠硬件来完成对文件的读取操作。

#include 
#include
#include
/*[chenndao@localhost log]$ gcc -o logreadapi logreadapi.c[chenndao@localhost log]$ ./logreadapi 3000000.txtFinished, total 3000000 linesCost time: 72 sec[chenndao@localhost log]$ */int main( int argc, char *argv[] ){  //Caculate how many lines in the log file.  if ( argc != 2 )    {      printf("usage: \n readlog log.txt\n");      return 0;    }  int lineNum = 0;  char buff[256] = { 0 };  time_t timeStart = time( NULL );  char *data = NULL;  int fd = open( argv[1], O_RDONLY );  if ( fd > 0 )    {      int len = 0;      do {   len = read( fd, buff, 256 );   if ( len > 0 )     {       int i = 0;       for( ; i
0 );      printf("Finished, total %d lines\n", lineNum);      printf("Cost time: %d sec\n", time(NULL)-timeStart);    }  else    {      printf("Open file %s error\n", argv[1]);    }return 1;}
#include 
#include
/*[chenndao@localhost log]$ ./logread 3000000.txtFinished, total 3000000 linesCost time: 20 sec*/int main( int argc, char *argv[] ){  //Caculate how many lines in the log file.  if ( argc != 2 )    {      printf("usage: \n readlog log.txt\n");      return 0;    }  int lineNum = 0;  char buff[256] = { 0 };  time_t timeStart = time( NULL );  char *data = NULL;  FILE *fd = fopen( argv[1], "r" );  if ( fd != NULL )    {      int len = 0;      do {   data = fgets( buff, 256, fd );   if ( data != NULL )     {       int i = 0;       for( ; i<256; i++)  {    if ( buff[i] == '\n' )      {        lineNum++;        break;      }  }     } }      while ( data );      printf("Finished, total %d lines\n", lineNum);      printf("Cost time: %d sec\n", time(NULL)-timeStart);    }  else    {      printf("Open file %s error\n", argv[1]);    }return 1;}
#include 
#include
#include
#include
/*[chenndao@localhost log]$ ./maplogread 3000000.txtFinished, total lines is 3000000 total costed time 0 sec[chenndao@localhost log]$ ./maplogread 3000000.txtFinished, total lines is 3000000 total costed time 1 secs*/int main( int argc, char *argv[] ){ if ( argc != 2 ) { printf("usage: \n maplogread 50000.txt\n"); return 0; } char *memory = NULL; int file_length = 0; char *start_address = 0; int line_num = 0; int time_start = time(NULL); int fd = open( argv[1], O_RDONLY ); if ( fd > 0 ) { file_length = lseek(fd, 1, SEEK_END); memory = mmap( start_address, file_length, PROT_READ, MAP_SHARED, fd, 0 ); int i=0; for ( ; i

转载地址:http://vdixi.baihongyu.com/

你可能感兴趣的文章
大学应该学的软件知识
查看>>
腾讯与360战争背后的云计算阴影
查看>>
腾讯看了会沉默,360看了会流泪
查看>>
李开复:移动互联网机会最大 微博会现最大赢家
查看>>
2006年的IT十大战略技术
查看>>
操作系统介绍
查看>>
Desktop Linux: The Dream Is Dead
查看>>
我的9年IT路
查看>>
任正非:让用户像用电一样享受云计算
查看>>
学习技术的几个境界
查看>>
计算机世界:免费的代价
查看>>
方兴东:中国网站十年
查看>>
2010年微软和谷歌十大战场:从桌面到浏览器
查看>>
服务器虚拟化的未来之路
查看>>
写给我们这些浮躁的系统工程师
查看>>
和平分手?你根本不知道吴恩达在百度经历了什么
查看>>
业余研究:关于腾讯与他的QQ帝国
查看>>
马云校长湖畔大学第三期讲义完整版
查看>>
iPhone为什么比Android好
查看>>
小程序的今天就是微信指数的明天
查看>>