Chinaunix首页 | 论坛 | 博客
  • 博客访问: 79273
  • 博文数量: 83
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 20
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-30 00:36
文章分类

全部博文(83)

文章存档

2014年(83)

我的朋友

分类: C/C++

2014-07-17 15:50:25

原文地址:mmap和madvise一起使用例子 作者:bjpiao

man madvise 
#include  
int madvise(void *addr, size_t length, int advice);

The madvise() system call advises the kernel about how to handle paging input/output in the address range beginning at address addr and with size length bytes. It allows an application to tell the kernel how it expects to use some mapped or shared memory areas, so that the kernel can choose appropriate read-ahead and caching techniques. This call does not influence the semantics of the application (except in the case of MADV_DONTNEED), but may influence its performance. The kernel is free to ignore the advice.

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <sys/mman.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <unistd.h>

  8. #include <time.h>
  9. #include <sys/time.h>

  10. #define FILE_LEGNTH (1000*1024*1024) /*200MB的文件*/

  11. #define TIMER(val) do{\
  12.                 struct timeval tm;\
  13.                 gettimeofday(&tm, NULL);\
  14.                 val = tm.tv_sec * 1000 + tm.tv_usec/1000;\
  15.         }\
  16.         while(0)

  17. //返回耗时
  18. int doprocess(char *p)        
  19. {
  20.     //下面开始逐个字符读取
  21.     long starttime, endtime;
  22.     TIMER(starttime);
  23.     int nSum = 0;
  24.     int i;
  25.     for (i=0; i<FILE_LEGNTH; i++)
  26.     {
  27.         nSum += *p;
  28.         p++;
  29.     }
  30.     TIMER(endtime);    
  31.     return (endtime - starttime);
  32. }
  33.         
  34. /// 创建一个大的空文件
  35. void CreateFile(const char *filepath)
  36. {
  37.     int fd = open(filepath, O_CREAT | O_RDWR);
  38.     if (fd<1)
  39.     {
  40.         perror("open error");
  41.         return;
  42.     }
  43.     lseek(fd, FILE_LEGNTH-1, SEEK_SET);
  44.     write(fd, "\0", 1);
  45.     close(fd);
  46.     fd = -1;
  47. }

  48. /// 顺序读
  49. void SequenceRead(const char *filepath)
  50. {
  51.     int fd = open(filepath, O_RDWR | O_EXCL);
  52.     if (-1==fd)
  53.     {
  54.         perror("open error");
  55.         return;
  56.     }
  57.     void* p = mmap(NULL, FILE_LEGNTH, PROT_READ, MAP_SHARED, fd, 0);
  58.     if (MAP_FAILED==p)
  59.     {
  60.         perror("map error");
  61.         return;
  62.     }
  63.     close(fd);
  64.     fd = -1;
  65.     
  66.     //内存使用建议
  67.     if (-1==madvise(p, FILE_LEGNTH, MADV_WILLNEED | MADV_SEQUENTIAL))
  68.     {
  69.         perror("madvise error");
  70.         return;
  71.     }
  72.     
  73.     //下面开始逐个字符读取
  74.     int interval = doprocess((char *)p);
  75.     printf("sequence read time: %d\n", interval);

  76.     if (-1==munmap(p, FILE_LEGNTH))
  77.     {
  78.         perror("unmap error");
  79.         return;
  80.     }
  81. }

  82. /// 随机读
  83. void RandomRead(const char *filepath)
  84. {
  85.     int fd = open(filepath, O_RDWR);
  86.     if (-1==fd) {
  87.         perror("open error");
  88.         return;
  89.     }
  90.     
  91.     // 建立匿名映射
  92.     void* p = mmap(NULL, FILE_LEGNTH, PROT_READ, MAP_SHARED, fd, 0);
  93.     if (MAP_FAILED==p) {
  94.         perror("map error");
  95.         return;
  96.     }
  97.     close(fd);
  98.     fd = -1;
  99.     
  100.     //内存使用建议
  101.     if (-1==madvise(p, FILE_LEGNTH, MADV_RANDOM))
  102.     {
  103.         perror("madvise error");
  104.         return;
  105.     }
  106.   
  107.     //下面开始逐个字符读取
  108.     int interval = doprocess((char *)p);
  109.     printf("random read time: %d\n", interval);
  110.     if (-1==munmap(p, FILE_LEGNTH))
  111.     {
  112.         perror("unmap error");
  113.         return;
  114.     }
  115. }

  116. /// without madvise
  117. void WithMadviseRead(const char *filepath)
  118. {
  119.     int fd = open(filepath, O_RDWR);
  120.     if (-1==fd) {
  121.         perror("open error");
  122.         return;
  123.     }
  124.     
  125.     // 建立匿名映射
  126.     void* p = mmap(NULL, FILE_LEGNTH, PROT_READ, MAP_SHARED, fd, 0);
  127.     if (MAP_FAILED==p) {
  128.         perror("map error");
  129.         return;
  130.     }
  131.     close(fd);
  132.     fd = -1;
  133.      
  134.     //下面开始逐个字符读取
  135.     int interval = doprocess((char *)p);
  136.     printf("without madvise read time: %d\n", interval);
  137.     if (-1==munmap(p, FILE_LEGNTH))
  138.     {
  139.         perror("unmap error");
  140.         return;
  141.     }
  142. }

  143. int main()
  144. {
  145.     const char path[100] = "/home/test3";
  146.     CreateFile(path);
  147.     RandomRead(path);
  148.     SequenceRead(path);
  149.     WithMadviseRead(path);
  150.     return 1;
  151. }

编译: g++ madvise-test.c
阅读(621) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~