mmap内存映射
内存共享定义
内存映射,简而言之就是将用户空间的一段内存区域映射到内核空间,映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,同样,内核空间对这段区域的修改也直接反映用户空间。那么对于内核空间<---->用户空间两者之间需要大量数据传输等操作的话效率是非常高的。
以下是一个把普遍文件映射到用户空间的内存区域的示意图
mmap内存映射方法
mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。
实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段虚拟内存,而系统会自动回写到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。
相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。如下图所示:
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
参数说明:
参数start:指向欲映射的内存起始地址,通常设为 NULL,代表让系统自动选定地址,映射成功后返回该地址。
参数length:代表将文件中多大的部分映射到内存。
参数prot:映射区域的保护方式。可以为以下几种方式的组合:
PROT_READ(可读)
PROT_WRITE(可写)
PROT_EXEC(可执行)
PROT_NONE(不可访问)
参数flags:由以下几个常值指定:
MAP_SHARED(共享的)
MAP_PRIVATE(私有的)
MAP_FIXED(表示必须使用 start 参数作为开始地址,如果失败不进行修正)
其中,MAP_SHARED , MAP_PRIVATE必选其一,而 MAP_FIXED 则不推荐使用。MAP_ANONYMOUS(匿名映射,用于血缘关系进程间通信)
参数fd:表示要映射的文件句柄。如果匿名映射写-1。
参数offset:表示映射文件的偏移量,一般设置为 0 表示从文件头部开始映射。offset必须是分页大小的整数倍(一般是4096的整数倍)。
写共享文件
#include"stdio.h"
#include"unistd.h"
#include"string.h"
#include"fcntl.h"
#include"sys/mman.h"
#include"sys/stat.h"
#include"stdlib.h"
#include"sys/types.h"
int main(int agrc,char* agrv[])
{
int len;
int fd;
void* map;
fd = open("1.txt",O_RDWR);
if(fd<0)
{
perror("open");
return -1;
}
len = lseek(fd, 0, SEEK_END)