1. mmap—创建内存映射
- 函数原型
void *mmap(
void *addr, //映射区首地址,传NULL
size_t length, //映射区大小(一般指定为文件fd的大小)
非0
实际大小是4K的整数倍
int prot, //映射区权限
PORT_READ----映射区必须有PORT_READ权限
PORT_WRITE
PORT_READ | PORT_WRITE
int flags, //标志位参数
MAP_SHARED 修改了内存,数据会同步到磁盘
MAP_PRIVATE 修改了内存,数据不会同步到磁盘
int fd, //文件描述符
要映射的文件对应的fd
off_t offset //映射文件的偏移量(一般设为0)
偏移量必须是4K的整数倍
);
- 作用:将磁盘文件的数据映射到内存,用户通过[修改内存]就能修改磁盘文件
- 返回值:
成功:指向映射区首地址的指针
失败:MAP_FAILED(-1)
2. munmap-释放内存映射区
int munmap(void *addr, size_t len);
- 参数:
addr:mmap的返回值
len:mmap的第二个参数
3. 思考问题
- 如果对mmap的返回值ptr做++操作,munmap是否能够成功?
答:不能成功 - open文件时,指定的是O_RDONLY,但是创建映射区时,指定的是PROT_READ|PROT_WRITE,能否成功?
答:不能成功,错误为—>mmap: Permission denied
规则:open文件指定的权限应该 ≥ mmap第三个参数prot指定的权限 - 如果文件的偏移量设置为1000会怎么样?
答:mmap调用失败,即偏移量必须是4096的整数倍 - 什么情况下mmap会调用失败?
1.第二个参数len=0
2.第三个参数必须指定PROT_READ
3.偏移量必须是4096的整数倍 - open的时候,用O_CREAT一个新文件后,mmap创建映射区可以成功么?
答:不能mmap成功,因为O_CREAT新创建文件后,大小为0---->要想mmap成功,需要先对文件进行大小扩展(lseek/truncate) - mmap后关闭文件描述符,对mmap映射有没有影响?
答:没有影响。 - 对ptr越界操作会怎么样?
答:段错误
4. 案例
int main(){
int fd=open("pipe.c",O_RDWR); //打开文件fd
if(fd==-1){
perror("open");
exit(1);
}
int len=lseek(fd,0,SEEK_END); //获取文件大小
void* ptr=mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);//创建映射区
if(ptr==MAP_FAILED){
perror("mmap");
exit(1);
}
printf("%s\n",(char*)ptr); //使用ptr指针访问mmap中的内容
int ret=munmap(ptr,len); //销毁mmap映射区
if(ret==-1){
perror("munmap fail\n");
exit(1);
}
return 0;
}