mmap
mmap的作用是将磁盘文件的数据映射到内存,用户通过修改内存就能修改磁盘文件。
1.函数原型:void *mmap(void *addr,size_t length,int prot,int flags,int fd,off_t offset);
addr:映射区的首地址,可以传NULL
length:映射区的大小,一般为4k的倍数。如传100,大小也为4k。一般传入文件的大小
prot:映射区权限。权限有读权限(必须)PROT_READ,写权限(可选)PROT_WRITE
flags:标志位参数。MAP_SHARED,修改了内存后,数据会同步到磁盘;
MAP_PRIVATE,修改了内存后,数据不会同步到磁盘。
fd:将要映射的文件的文件描述符
offset:映射文件的偏移量,必须是4k的整数倍,一般传0
2.返回值:成功:返回映射区首地址
失败:返回一个宏MAP_FAILED
3.munmap
释放内存映射区
函数原型:int munmap(void *addr,size_t length);
addr:mmap的返回值,映射区首地址
length:mmap的第二个参数,映射区长度
mmap的使用
1 #include <sys/mman.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <fcntl.h> 5 #include <unistd.h> 6 7 int main() 8 { 9 int fd = open("chinese.txt",O_RDWR); 10 if(fd == -1){ 11 perror("open error:"); 12 exit(-1); 13 } 14 int len = lseek(fd,0,SEEK_END); 15 printf("file size is %d\n",len); 16 char *ptr = (char *)mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0); 17 18 if(ptr==MAP_FAILED){ 19 perror("mmap error:"); 20 exit(-1); 21 } 22 printf("%s\n",ptr); 23 24 munmap(ptr,len); 25 close(fd); 26 return 0; 27 }
4.进程间通信
有血缘关系的进程之间:父子进程共享内存映射区(有名映射区)
1 #include <sys/mman.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <fcntl.h> 5 #include <unistd.h> 6 #include <sys/wait.h> 7 #include <string.h> 8 9 int main() 10 { 11 int fd = open("chinese.txt",O_RDWR); 12 if(fd == -1){ 13 perror("open error:"); 14 exit(-1); 15 } 16 int len = lseek(fd,0,SEEK_END); 17 printf("file size is %d\n",len); 18 char *ptr = (char *)mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0); 19 20 if(ptr==MAP_FAILED){ 21 perror("mmap error:"); 22 exit(-1); 23 } 24 // printf("%s\n",ptr); 25 26 pid_t pid = fork(); 27 if(pid == -1){ 28 perror("fork error:"); 29 exit(-1); 30 } 31 32 if(pid > 0){ 33 strcpy(ptr,"你是我儿吗"); 34 wait(NULL); 35 }else if(pid == 0){ 36 printf("%s\n",ptr); 37 } 38 39 munmap(ptr,len); 40 close(fd); 41 return 0; 42 }
匿名映射区
#include <sys/mman.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/wait.h> #include <string.h> int main() { int len = 4096; char *ptr = (char *)mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0); if(ptr==MAP_FAILED){ perror("mmap error:"); exit(-1); } // printf("%s\n",ptr); pid_t pid = fork(); if(pid == -1){ perror("fork error:"); exit(-1); } if(pid > 0){ strcpy(ptr,"你是我儿吗"); wait(NULL); }else if(pid == 0){ printf("%s\n",ptr); } munmap(ptr,len); return 0; }
没有血缘关系的进程之间:不能借助匿名映射区的方式,只能借助磁盘文件映射的方式
写端:
1 #include <sys/mman.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <fcntl.h> 5 #include <unistd.h> 6 #include <sys/wait.h> 7 #include <string.h> 8 9 int main() 10 { 11 int fd = open("temp",O_RDWR|O_CREAT,0664); 12 if(fd == -1){ 13 perror("open error:"); 14 exit(-1); 15 } 16 17 int len = lseek(fd,0,SEEK_END); 18 char *ptr = (char *)mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0); 19 20 if(ptr==MAP_FAILED){ 21 perror("mmap error:"); 22 exit(-1); 23 } 24 // printf("%s\n",ptr); 25 26 while(1){ 27 sleep(2); 28 char *ptemp = ptr+1024; 29 strcpy(ptemp,"你是我儿吗\n"); 30 } 31 32 close(fd); 33 munmap(ptr,len); 34 return 0; 35 }
读端:
1 #include <sys/mman.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <fcntl.h> 5 #include <unistd.h> 6 #include <sys/wait.h> 7 #include <string.h> 8 9 int main() 10 { 11 int fd = open("temp",O_RDWR|O_CREAT,0664); 12 if(fd == -1){ 13 perror("open error:"); 14 exit(-1); 15 } 16 17 ftruncate(fd,4096); //文件大小拓展 18 int len = lseek(fd,0,SEEK_END); 19 char *ptr = (char *)mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0); 20 21 if(ptr==MAP_FAILED){ 22 perror("mmap error:"); 23 exit(-1); 24 } 25 // printf("%s\n",ptr); 26 27 while(1){ 28 sleep(1); 29 printf("%s\n",ptr+1024); 30 } 31 32 close(fd); 33 munmap(ptr,len); 34 return 0; 35 }
5.创建匿名映射区的方法
mmap函数参数的改变:
第二个参数:改为要指定的映射区的大小,原来为文件的大小
第四个参数:需要添加MAP_ANON宏
第五个参数:-1,原来为fd

浙公网安备 33010602011771号