内存映射 mmap
内存映射mmap函数的作用是建立一段可以被两个或者多个程度读写的内存段,一个程序对他进行任何修改,对其它程序可见。同样,这个功能可以用在对文件的处理上,mmap函数创建一个指向一个内存区域的指针,该内存区域与可以通过一个打开的文件描述符访问的文件的内容相关联。
一、mmap函数
1 #include <sys/mman.h> 2 void *mmap(void *addr,size_t len,int prot,int flags,int filedes,off_t off);
参数说明:
1、addr:用来请求使用某个特定的内存地址。如果他取0,结果指针就将自动分配(这是推荐的做法)。否则会降低程序的可移植性,
因为不同系统的可用地址范围不一样。
2、len:可以访问的数量,即内存段的大小。
3、prot:用于设置内存段访问的权限
PROT_READ:允许读该内存段
PROT_WRITE:允许写该内存段
PROT_EXEC:允许执行该内存段
PROT_NONE:不能访问
4、flags:控制程序对内存段的改变所造成的影响
MAP_PRIVATE:内存段私有,对它的修改值对本进程有效
MAP_SHARED:把对该内存段的修改保存到磁盘文件中
MAP_FIXED:该内存段必须位于addr指定的地址处
5、filedes:打开的文件描述符
6、off:用以改变经共享内存段访问的文件中数据的起始偏移值
二、msync函数
1 #include <sys/mman.h> 2 int msync(void *addr,size_t len,int flags);
参数说明:
1、addr:共享内存起始位置
2、len: 映射的文件的长度
3、flags:控制执行修改的方式
MS_ASYNC 采用异步
MS_SYNC 采用同步
MS_INVALIDATE 从文件中读回数据
三、munmap函数—— 释放内存段
1 #include <sys/mman.h> 2 int munmap(void *addr,size_t len);
参数说明:
1、addr:共享内存起始位置
2、len: 映射的文件的长度
API的使用例子:
1 #include <unistd.h> 2 #include <stdio.h> 3 #include <sys/mman.h> 4 #include <fcntl.h> 5 #include <stdlib.h> 6 7 typedef struct record 8 { 9 int data; 10 char string[24]; 11 }RECORD; 12 13 #define N (100) 14 int main() 15 { 16 RECORD rec,*mapped; 17 int i,f; 18 FILE *fp; 19 fp = fopen("records.dat","w+");//以写的方式打开一个文件 20 for(i=0;i<N;i++) 21 { 22 rec.data = i; 23 sprintf(rec.string,"RECORD-%d",i); 24 fwrite(&rec,sizeof(RECORD),1,fp);//向文件中写一个记录 25 } 26 fclose(fp); 27 /////////////////////////////////////////////////////////// 28 29 f = open("records.dat",O_RDWR);//以读写的方式打开一个文件描述符 30 mmaped = (RECORD*)mmap(0,N*sizeof(RECORD),PROT_WRITE|PROT_READ,MAP_SHARED,f,0);//映射 31 mmaped[43].data = 123;//修改第43个记录的整型部分 32 sprintf(mmaped[43].string,"RECORD-%d",mmaped[43].data);//修改字符串部分 33 msync((void*)mmaped,N*sizeof(RECORD),MS_ASYNC);//将修改同步到文件 34 munmap((void*)mmaped,N*sizeof(RECORD));//释放内存段 35 close(f);//关闭文件描述符 36 return 0; 37 }