目录
- 内存映射
- 内存映射相关系统调用
- 内存映射的注意事项
- 如果对mmap的返回值(ptr)做++操作,释放内存(munmap)是否能够成功?
- 如果open时O_RDONLY,mmap时prot参数指定PROT_READ | PROT_WRITE会怎样?
- 如果文件偏移量为1000会怎样?
- mmap什么情况下会调用失败?
- open的时候O_CREAT一个新文件来创建映射区吗?
- mmap后关闭文件描述符,对mmap映射有没有影响?
- 对ptr越界操作会怎样?
- 内存映射完成文件复制
- 匿名映射
内存映射
将磁盘文件的数据映射到内存中,用户通过修改内存就能修改磁盘文件
内存映射相关系统调用
内存映射
void *mmap
释放内存
int munmap
#include<stdio.h>
#include<sys/mman.h>
#include<fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <wait.h>int main(){//1.打开一个文件int fd=open("test.txt",O_RDWR);int size=lseek(fd,0,SEEK_END);//获取文件大小//2.创建内存映射区void *ptr=mmap(NULL,size,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);if(ptr==MAP_FAILED){perror("mmap");exit(0);}//3.创建子进程pid_t pid=fork();if(pid>0){wait(NULL);//父进程char buf[64];strcpy(buf,(char *)ptr);printf("read data: %s\n",buf);}else if(pid==0){//子进程strcpy((char *)ptr,"nihao a,son!!!");}//关闭内存映射区munmap(ptr,size);return 0;
}
文件中的内容也被修改了
内存映射的注意事项
如果对mmap的返回值(ptr)做++操作,释放内存(munmap)是否能够成功?
不能,可以做++操作,但是不能正确释放,不是从首地址开始释放了,需要先保存地址
如果open时O_RDONLY,mmap时prot参数指定PROT_READ | PROT_WRITE会怎样?
会返回一个宏,map_failed,相当于-1
open函数中的权限建议和prot参数的权限保持一致
如果文件偏移量为1000会怎样?
偏移量必须是4k的整数倍,会返回map_failed
mmap什么情况下会调用失败?
length=0
权限不一致
open的时候O_CREAT一个新文件来创建映射区吗?
可以的,但是创建的文件的大小如果为0的话,肯定不行
可以对新的文件进行拓展,lseek来拓展,或者truncate
mmap后关闭文件描述符,对mmap映射有没有影响?
映射区还存在,创建映射区的fd被关闭,没有任何影响
对ptr越界操作会怎样?
越界操作操作的是非法的内存,会产生段错误
内存映射完成文件复制
//使用内存映射实现文件拷贝的功能
#include<stdio.h>
#include<sys/mman.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>int main(){//1.对原始的文件进行内存映射int fd=open("english.txt",O_RDWR);if(fd==-1){perror("open");exit(0);}//获取原始文件的大小int len=lseek(fd,0,SEEK_END);//2.创建一个新文件(拓展该文件)int fd1=open("cpy.txt",O_RDWR | O_CREAT,0664);if(fd==-1){perror("open");exit(0);}//对新创建的文件进行拓展truncate("cpy.txt",len);write(fd1,"",1);//3.分别做内存映射void * ptr =mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);void * ptr1=mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd1,0);if(ptr==MAP_FAILED){perror("mmap");exit(0);}if(ptr1==MAP_FAILED){perror("mmap");exit(0);}//内存拷贝memcpy(ptr1,ptr,len);//释放资源,先打开先释放munmap(ptr1,len);munmap(ptr,len);close(fd1);close(fd);return 0;
}
匿名映射
不需要文件实体进行内存映射
之前的都是文件映射,通过文件,共享文件
#include<stdio.h>
#include<sys/mman.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<wait.h>int main(){//1.创建匿名内存映射区int len=4096;void * ptr=mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0);if(ptr==MAP_FAILED){perror("mmap");exit(0);}//父子进程通信pid_t pid=fork();if(pid>0){//父进程strcpy((char *)ptr,"hello,world");wait(NULL);}else if(pid==0){//子进程sleep(1);printf("%s\n",(char *)ptr);}//释放内存映射区int ret=munmap(ptr,len);if(ret==-1){perror("munmap");exit(0);}return 0;
}
实现父子进程通信