Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1056520
  • 博文数量: 573
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 66
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-28 16:21
文章分类

全部博文(573)

文章存档

2018年(3)

2016年(48)

2015年(522)

分类: LINUX

2015-12-02 15:38:59

mmap.c文件

点击(此处)折叠或打开

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

  9. int main(int argc, char * * argv)
  10. {
  11.         int fd;
  12.         /*映射该文件到一个地址空间之前,先要打开该文件。*/
  13.         fd = open("mmap.txt", O_RDWR, 0777);
  14.         if(fd < 0)
  15.         {
  16.                 printf("open err!\n");
  17.                 exit(1);
  18.         }
  19.         
  20.         struct stat stat;
  21.         fstat(fd, &stat);
  22.         printf("文件[%s]大小stat.st_size=[%d]\n", "mmap.txt", stat.st_size);
  23.         
  24.         lseek(fd, sizeof(char)*40, SEEK_SET);
  25.         write(fd, "", 1); /*写一个字节,以设置文件长度*/
  26.         
  27.         int len = stat.st_size;
  28.         len = 20;
  29.         printf("len = [%d]\n", len);
  30.         /*将文件fd中的内容映射到内存中:mmap 实现共享内存也是其主要应用*/
  31.         char * mapbuf;
  32.         mapbuf = (char*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  33.         /*注意:所写内容不能超过文件大小,超过部分将会被截断*/
  34.         if(mapbuf == (void *)-1)
  35.         {
  36.                 printf("mmap err!\n");
  37.                 exit(1);
  38.         }
  39.         /*注意 1,如果len小于文件长度,则映射区大小就是len,文件中前len个字节被映射。
  40.                      2,如果len大于等于文件长度,则映射区大小就是文件长度,文件中全部内容被映射。
  41.                      3,最终被映射文件内容长度不会超过文件本身大小,即映射不能改变文件大小。
  42.                      4,如果另外一个进程也映射这个文件,这2个进程之间就可以实现共享内存了。
  43. 映射区有效地址空间大小大体上受限于被映射文件 大小 但不完全受限于文件大小:
  44. 打开文件被截短为5个people结构大小 而在 map_normalfile1 中开了10个people数据结构
  45. 在恰当时候(map_normalfile1输出initialize over 的后 输出umap ok的前)
  46. map_normalfile2 会发现 map_normalfile2 将输出全部10个people结构 值 后面将给出详细讨论
  47. :在linux中 内存 保护是以页为基本单位 即使被映射文件只有1个字节大小
  48. 内核也会为映射分配1个页面大小 内存 当被映射文件小于1个页面大小时
  49. 进程可以对从mmap 返回地址开始1个页面大小进行访问而不会出错;
  50. 但是 如果对1个页面以外 地址空间进行访问 则导致 发生 后面将进1步描述
  51. 因此 可用于进程间通信 有效地址空间大小不会超过文件大小及1个页面大小
  52. */
  53.         
  54.         char buf[1024];
  55.         memset(buf, 0, sizeof(buf));
  56.         strcpy(buf, "+++++++++++++++++++++++++\n");
  57.         //strcat(buf, "789\n");
  58.         strcpy(buf, "3333abcdefghijklmnopqrst111111111111111111111111111111111111111\n");
  59.         printf("strlen(buf)=[%d]\n", strlen(buf));
  60.         
  61.         
  62.         /*对映射存储区执行memcpy时候,是从存储区的启始地址开始开始复制的,
  63.         最长不会超过存储映射区的空间大小。
  64.         进程可以像访问普通内存一样,对文件进行访问,不必read,write*/
  65.         memcpy(mapbuf, buf, strlen(buf));
  66.         /*注意:向映射区所写内容不能超过文件大小,超过部分将会被截断*/
  67.         //strcat(mapbuf, buf);
  68.         printf("mapbuf=[%s]\n", mapbuf);
  69.         /*memcpy中buf的内容超过文件长度的时候,打印出来的mapbuf也是buf的全部内容:
  70.         是因为没遇到字符串结束标志,mapbuf在内存中最大只有文件长度大小,这里超过了,
  71.         其实mmebuf已经溢出了。超过的部分不会写到文件里面,所以就发生了截断。*/
  72.         //write(1, mapbuf, stat.st_size);
  73.         
  74.         sleep(10);
  75.         
  76.         /*将修改写回映射文件中,采用异步写方式*/
  77.         msync(mapbuf, len, MS_ASYNC);
  78.         
  79.         /*存储映射区解除映射关系:释放内存,不会使映射区的内容写到磁盘文件上*/
  80.         munmap(mapbuf, len);
  81.         
  82.         
  83.         
  84.         close(fd);
  85.         
  86.         return 0;
  87. }
mmap2.c文件

点击(此处)折叠或打开

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

  9. typedef struct{
  10.         char name[128];
  11.         char age[16];
  12. }people;

  13. int main(int argc, char* * argv) // map a normal file as shared mem:
  14. {
  15.         int fd,i;
  16.         people * p_map;
  17.         char temp[128];

  18.         fd=open("mmap2.txt", O_CREAT|O_RDWR|O_TRUNC, 0777);
  19.         lseek(fd, sizeof(people)*5-1, SEEK_SET);
  20.         write(fd, "", 1); /*写一个字节,以设置输出文件长度*/

  21.         p_map = (people*)mmap(NULL, sizeof(people)*5-1, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  22.         close(fd);
  23.         strcpy(temp, "wangxiancai");
  24.         for(i=0; i<10; i++)
  25.         {
  26.                 memcpy((*(p_map+i)).name, temp, 4);
  27.                 memcpy((*(p_map+i)).age, "18", 2);
  28.                 printf("[%d].name=[%s], [%d].age=[%s]\n", i, (*(p_map+i)).name, i, (*(p_map+i)).age);
  29.         }
  30.         printf("initialize over!\n");
  31.         sleep(10);

  32.         munmap(p_map, sizeof(people)*5);
  33.         printf("umap ok!\n");
  34.         
  35.         return 0;
  36. }
mmap3.c文件

点击(此处)折叠或打开

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

  9. typedef struct{
  10.         char name[128];
  11.         char age[16];
  12. }people;
  13.  
  14. int(int argc, char * * argv)
  15. {
  16.         int i;
  17.         people * p_map;
  18.         char temp;
  19.         p_map=(people*)mmap(NULL, (people)*10, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
  20.         /*匿名映射:子进程可以继承父进程的映射区,所以父子进程可以实现共享内存,无法和其他进程共享内存。*/
  21.         if(fork() == 0)
  22.         {
  23.                 sleep(2);
  24.                 for(i = 0; i<5; i)
  25.                 prinf("child read: the %d people's age is %d\n", i+1, (*(p_map+i)).age);
  26.                 (*p_map).age = 100;
  27.                 
  28.                 munmap(p_map, (people)*10); //实际上 进程终止时 会自动解除映射
  29.                 exit ;
  30.         }
  31.         temp = 'a';
  32.         for(i=0;i<5; i)
  33.         {
  34.                 temp 1;
  35.                 memcpy((*(p_map+i)).name, &temp,2);
  36.                 (*(p_map+i)).age=20+i;
  37.         }

  38.         sleep(5);
  39.         prinf("parent read: the first people,s age is %d/n",(*p_map).age );
  40.         prinf("umap!\n");
  41.         munmap(p_map, (people)*10 );
  42.         prinf("umap ok!\n");
  43. }



阅读(683) | 评论(0) | 转发(0) |
0

上一篇:gethostent函数

下一篇:getnetent函数

给主人留下些什么吧!~~