赣州建设局网站,十大招商平台,电脑浏览器打不开网页,远程wordpress数据库学习这篇博客#xff0c;进行了一些归纳Linux下mmap_linux mmap_一个山里的少年的博客-CSDN博客https://blog.csdn.net/qq_56999918/article/details/127070280
读取文件
读取文件方法#xff1a;由操作系统提供的两个方法#xff0c;read和write来读写文件。
由… 学习这篇博客进行了一些归纳Linux下mmap_linux mmap_一个山里的少年的博客-CSDN博客https://blog.csdn.net/qq_56999918/article/details/127070280
读取文件
读取文件方法由操作系统提供的两个方法read和write来读写文件。
由于read和write是系统调用需要先从用户态进入到内核态再将磁盘中的数据拷贝到操作系统的缓冲区中然后再将缓冲区中的数据拷贝到用户态中这个过程进行了两次拷贝。 mmap
① memory map:是一种内存映射文件的方法。
② mmap是一个可以将一个文件或者其他对象映射到进程的地址空间实现磁盘的地址和进程虚拟地址空间一段虚拟地址的一一对应关系。
③ mmap系统调用可以让进程之间通过映射到同一个普通文件实现共享内存普通文件被映射到进程地址空间当中之后进程可以向访问普通内存一样对文件进行一系列操作。 【总结】 ① 日常中使用read或者write需要进行两次拷贝一次是将文件拷贝到内核缓冲区一次是从内核缓冲区拷贝到用户缓冲区。 ② 使用mmap可以减少第二次拷贝由于内核将文件映射到内存之后用户进程就可以操作这些数据了用户进程只需要修改内核中的内容接着通过内核的内存管理器自动将这些数据刷新到磁盘当中。 ③ mmap可以提高内存性能内核空间和用户空间共用一个缓冲区当多个进程正在对同一个文件进行IO操作那么通过使用mmap能够共享一个内核缓冲区从而可以减少内存消耗。 用户态中的mmap函数以及相关参数详解
mmap的使用#include sys/mman.hvoid *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);函数说明创建虚拟内存到物理内存或者文件的映射参数- addr映射区的起始地址如果是NULL系统自动分配- length字节长度自动按照4KB对齐建议大小一般填成4KB的整数倍- prot映射区域的权限- flags映射的标志位- fd文件描述符- offset文件偏移量自动按照4KB对齐prot 的取值PORT_EXEC:映射的区域具有可执行权限PROT_READ:映射的区域具有可读权限PROT_WRITE:映射区域具有可写权限PROT_NONE:映射区域不可被访问对应flags的取值MAP_SHARED:对映射区域的写入操作直接反映到文件中MAP_FIXED:若在start上无法创建映射则失败如果没有此标记会自动创建MAP_PRIVATE:对映射区域的写入操作只反映到缓冲区当中不会写入到真正的文件MAP_ANONYMOUS:匿名映射将虚拟地址映射到物理内存而不是文件忽略fd)MAP_DENYWRITE:拒绝其它文件的写入操作MAP_LOCKED:锁定映射区域保证其不被置换返回值函数的返回值为最后文件映射到进程空间的地址进程可直接操作起始地址为该值的有效地址 内核态中的mmap函数
int mmap(struct file* filp,struct vm_area_struct* vma),
用户态的mmap函数实现映射到物理内存
#include iostream
#include sys/mman.h
#include cstring
#include cerrno
#include cstdio
using namespace std;
static const int SIZE 4096;
int main()
{char *str (char *)mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);//注意MAP_PRIVATE和MAP_SHARED//建立映射if (str MAP_FAILED){printf(%s\n, strerror(errno));return -2;}strcpy(str, hello ksy);puts(str);//用于取消映射munmap(str, SIZE);return 0;
} 用户态的mmap函数实现映射到文件
#include iostream
#include sys/mman.h
#include cstring
#include cerrno
#include cstdio
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include unistd.h
using namespace std;
static const int SIZE 4096;
int main()
{int fd open(./a.txt, O_RDWR | O_CREAT, 0644);truncate(a.txt, 1024);if (fd 0){printf(%s\n, strerror(errno));return -1;}char *str (char *)mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);//注意MAP_PRIVATE和MAP_SHARED//建立映射if (str MAP_FAILED){printf(%s\n, strerror(errno));close(fd);return -2;}strcpy(str, helloworld);close(fd);return 0;
} 【注意】 如果不加truncate(a.txt, 1024);会出现总线错误 (核心已转储) 【原因】mmap是虚拟内存映射到文件物理内存。由于heheda.txt是新创建的也就是0个字节。那么在映射时候也是映射了0个字节这个文件映射过来的内存是没有的所以我们往里面写东西就会崩溃truncate函数对文件提前处理一下 int truncate(const char *path, off_t length); 函数说明truncate()会将参数path指定的文件大小改为参数length指定的大小。 如果原来的文件大小比参数length大则超过的部分会被删除。可以提前使用这个函数提前将文件的大小进行设置就可以向映射的这块内存进行写入了。也就可以成功将其写入到文件中了