mmap的用法

合集下载

mmap函数参数讲解

mmap函数参数讲解

mmap函数参数讲解1.mmap-创建内存映射作⽤:将磁盘⽂件的数据映射到内存,⽤户通过内存就能修改磁盘⽂件函数原型:void *mmap{void *addr; //映射区⾸地址,传NULLsize_t length; //映射区的⼤⼩//会⾃动调为4k的整数倍//不能为0//⼀般⽂件多⼤,length就指定多⼤int prot; //映射区权限//PROT_READ 映射区⽐必须要有读权限//PROT_WRITE//PROT_READ | PROT_WRITEint flags; //标志位参数//MAP_SHARED 修改了内存数据会同步到磁盘//MAP_PRIVATE 修改了内存数据不会同步到磁盘int fd; //要映射的⽂件对应的fdoff_t offset; //映射⽂件的偏移量,从⽂件的哪⾥开始操作//映射的时候⽂件指针的偏移量//必须是4k的整数倍//⼀般设置为0}返回值:映射区的⾸地址-调⽤成功调⽤失败:MAP_FALED2.munmap-释放内存映射区函数原型:int munmap(void *addr,size_t length);addr-mmap的返回值length-mmap的第⼆个参数3.注意事项问:如果对mmap的返回值(ptr)做++操作(ptr++), munmap是否能够成功?答:不能问:如果open时O_RDONLY, mmap时prot参数指定PROT_READ | PROT_WRITE会怎样? 答mmap调⽤失败open⽂件指定权限应该⼤于等于mmap第三个参数prot指定的权限问:如果⽂件偏移量为1000会怎样?答:必须是4096的整数倍问:mmap什么情况下会调⽤失败?第⼆个参数length = 0第三个参数必须指定PROT_READfd对应的打开权限必须⼤于等于port权限偏移量:必须是4096的整数倍问:可以open的时候O_CREAT⼀个新⽂件来创建映射区吗?答:可以,需要做⽂件拓展lseektruncate(path,length)问:mmap后关闭⽂件描述符,对mmap映射有没有影响?答:没有问:对ptr越界操作会怎样?答:段错误4.mmap使⽤(1)基本代码#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>#include <sys/mman.h>#include <fcntl.h>int main(int argc, const char* argv[]){//打开⼀个⽂件int fd=open("english.txt",O_RDWR);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 error");exit(1);}printf("%s",(char*)ptr);//释放内存映射区munmap(ptr,len);close(fd);return 0;}运⾏结果:wangkai@wangkai-HP-242-G1-Notebook-PC:~/0110/6Day$ ./mmap sadaskdkasjsdasdasdasdasdsadasdsdasdas(2)使⽤mmap进⾏有⾎缘关系的进程间通信#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>#include <sys/mman.h>#include <sys/wait.h>#include <fcntl.h>/*利⽤mmap进⾏⽗⼦间通信,效率⽐⽂件I/O⾼,数据不是从磁盘上读,⽽是从内存上读写不阻塞,所以读之前⼀定要写好*/int main(int argc, const char* argv[]){//打开⼀个⽂件int fd=open("english.txt",O_RDWR);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 error");exit(1);}close(fd);//创建⼦进程pid_t pid=fork();if(pid==-1){perror("fork error");exit(1);}if(pid>0){//写数据strcpy((char*)ptr,"我是你爸爸");//回收⼦进程wait(NULL);}else if(pid==0){//读数据printf("%s\n",(char*)ptr);}printf("%s",(char*)ptr);//释放内存映射区munmap(ptr,len);return 0;}(3)创建匿名映射区int len=4096;//创建匿名内存映射区,不指定⽂件void *ptr=mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANON,-1,0);效果和(2)⼀样。

mmap和普通文件读写的区别和比较mmap的注意点

mmap和普通文件读写的区别和比较mmap的注意点

mmap和普通⽂件读写的区别和⽐较mmap的注意点参考对linux⽂件系统不了解的朋友,请参阅我之前写的博⽂《》,我们⾸先简单的回顾⼀下常规⽂件系统操作(调⽤read/fread等类函数)中,函数的调⽤过程:1、进程发起读⽂件请求。

2、内核通过查找进程⽂件符表,定位到内核已打开⽂件集上的⽂件信息,从⽽找到此⽂件的inode。

3、inode在address_space上查找要请求的⽂件页是否已经缓存在页缓存中。

如果存在,则直接返回这⽚⽂件页的内容。

4、如果不存在,则通过inode定位到⽂件磁盘地址,将数据从磁盘复制到页缓存。

之后再次发起读页⾯过程,进⽽将页缓存中的数据发给⽤户进程。

总结来说,常规⽂件操作为了提⾼读写效率和保护磁盘,使⽤了页缓存机制。

这样造成读⽂件时需要先将⽂件页从磁盘拷贝到页缓存中,由于页缓存处在内核空间,不能被⽤户进程直接寻址,所以还需要将页缓存中数据页再次拷贝到内存对应的⽤户空间中。

这样,通过了两次数据拷贝过程,才能完成进程对⽂件内容的获取任务。

写操作也是⼀样,待写⼊的buffer在内核空间不能直接访问,必须要先拷贝⾄内核空间对应的主存,再写回磁盘中(延迟写回),也是需要两次数据拷贝。

⽽使⽤mmap操作⽂件中,创建新的虚拟内存区域和建⽴⽂件磁盘地址和虚拟内存区域映射这两步,没有任何⽂件拷贝操作。

⽽之后访问数据时发现内存中并⽆数据⽽发起的缺页异常过程,可以通过已经建⽴好的映射关系,只使⽤⼀次数据拷贝,就从磁盘中将数据传⼊内存的⽤户空间中,供进程使⽤。

总⽽⾔之,常规⽂件操作需要从磁盘到页缓存再到⽤户主存的两次数据拷贝。

⽽mmap操控⽂件,只需要从磁盘到⽤户主存的⼀次数据拷贝过程。

说⽩了,mmap的关键点是实现了⽤户空间和内核空间的数据直接交互⽽省去了空间不同数据不通的繁琐过程。

因此mmap效率更⾼。

mmap优点总结由上⽂讨论可知,mmap优点共有⼀下⼏点:1、对⽂件的读取操作跨过了页缓存,减少了数据的拷贝次数,⽤内存读写取代I/O读写,提⾼了⽂件读取效率。

mmap概述

mmap概述

mmap概述mmap/munmap接⼝是⽤户空间的最常⽤的⼀个系统调⽤接⼝,⽆论是在⽤户程序中分配内存、读写⼤⽂件,链接动态库⽂件,还是多进程间共享内存,都可以看到mmap/munmap的⾝影。

mmap/munmap函数声明如下:#include <sys/mman.h>void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);int munmap(void *addr, size_t length);addr:⽤于指定映射到进程空间的起始地址,为了应⽤程序的可移植性,⼀般设置为NULL,让内核来选择⼀个合适的地址。

length:表⽰映射到进程地址空间的⼤⼩prot:⽤于设置内核映射区域的读写属性等。

flags:⽤于设置内存映射的属性,例如共享映射、私有映射等。

fd:表⽰这个是⼀个⽂件映射,fd是打开⽂件的句柄。

offset:在⽂件映射时,表⽰⽂件的偏移量。

prot参数通常表⽰映射页⾯的的读写权限,可以有如下参数组合:PROT_EXEC:表⽰映射的页⾯是可以执⾏的。

PROT_READ:表⽰映射的页⾯是可以读取的。

PROT_WRITE:表⽰映射的页⾯是可以写⼊的。

PROT_NONE:表⽰映射的页⾯是不可访问的。

flags参数也是⼀个重要的参数,有如下常见的参数:MAP_SHARED:创建⼀个共享映射的区域。

多个进程可以通过共享映射⽅式来映射⼀个⽂件,这样其他进程也可以看到映射内容的改变,修改后的内容会同步到磁盘⽂件中。

MAP_PRIVATE:创建⼀个私有的写时复制的映射。

多个进程可以通过私有映射的⽅式来映射⼀个⽂件,这样其他进程不会看到映射内容的改变,修改后的内容也不会同步到磁盘⽂件中。

MAP_ANONYMOUS:创建⼀个匿名映射,即没有关联到⽂件的映射。

MAP_FIXED:使⽤参数addr创建映射,如果内核⽆法映射指定地址addr,那么mmap会返回失败,参数addr要求按页对齐。

大页内存--mmap

大页内存--mmap

⼤页内存--mmap1.为什么要使⽤⼤页内存 了解操作系统内存管理的⼈⼀般都知道操作系统对内存采⽤多级页表和分页进⾏管理,操作系统每个页默认⼤⼩为4KB。

如果进程使⽤的内存过⼤,⽐如1GB,这样会在页表中占⽤ 1GB / 4KB = 262144个页表项,⽽系统TLB可以容纳的页表项远⼩于这个数量。

当多个内存密集型应⽤访问内存时,会造成过多的TLB未命中,因此在特定情况下会需要减少未命中次数,⼀个可⾏的办法就是增⼤每个页的尺⼨。

操作系统默认⽀持的⼤页是2MB,当使⽤1GB内存时,在页表中将占⽤ 1GB / 2MB = 512个页表项,可以⼤⼤提升TLB命中率,进⽽提升应⽤性能。

2.怎样使⽤⼤页内存2.1 先预留⼀定量的⼤页内存#先查看系统有多少已经预留的⼤页内存# cat /proc/meminfo |grep -i huge#预留192个⼤页# sysctl vm.nr_hugepages=192#查看是否预留成功# cat /proc/meminfo |grep -i huge2.2 通过系统调⽤来从预留的⼤页内存中申请⼤页#include <sys/mman.h>#include <stdio.h>#include <memory.h>int main(int argc, char *argv[]) {char *m;size_t s = (8UL * 1024 * 1024);m = mmap(NULL, s, PROT_READ | PROT_WRITE,MAP_PRIVATE | MAP_ANONYMOUS | 0x40000 /*MAP_HUGETLB*/, -1, 0);if (m == MAP_FAILED) {perror("map mem");m = NULL;return 1;}memset(m, 0, s);printf("map_hugetlb ok, press ENTER to quit!\n");getchar();munmap(m, s);return 0;}3.最后的话⼤页内存的好处不仅是减少TLB未命中次数,⽽且⼤页内存分配的是物理内存,不会被操作系统的内存管理换出到磁盘上,因此不会出现缺页中断,也就不会引⼊访问磁盘的时延,另外,⼤页内存在物理上是连续的,对于⼤内存访问也有⼀定的加速效果。

mmap2 参数

mmap2 参数

mmap2 参数
`mmap2`是Linux系统中的一个系统调用,用于将文件或设备映射到内存中。

它的参数包括:
`void addr`:指定映射区域的起始地址。

通常可以设置为NULL,让内核自动选择一个合适的地址。

`size_t length`:指定要映射的字节数。

`int prot`:指定内存区域的保护权限。

常用的保护权限有`PROT_READ`(只读)、`PROT_WRITE`(可写)和`PROT_EXEC`(可执行)。

`int flags`:指定映射区域的类型。

常用的标志有`MAP_SHARED`(共享映射)和`MAP_PRIVATE`(私有映射)。

`int fd`:指定要映射的文件描述符。

如果映射的是设备,可以使用特殊的设备文件,如`/dev/zero`、`/dev/null`等。

`off_t offset`:指定文件或设备中的起始偏移量。

如果映射的是整个文件,通常可以设置为0。

返回值是映射区域的起始地址,如果出错则返回-1。

mmap文件修改内容的写回

mmap文件修改内容的写回

mmap⽂件修改内容的写回⼀、问题在Linux下,使⽤mmap是操作⽂件内容的⼀个⾮常⽅便的⽅法,它可以将相对受限的⽂件操作接⼝转换为⼤家喜闻乐见的内存操作。

这个本⾝可以引申出很多⽅便的操作,⽐如,我们可以将这个内存地址(也就是对应的⽂件的某个部分)转换为⼀个特定的数据结构指针,从⽽可以⽅便的进⾏结构的读取和修改。

⼤部分情况下,应⽤都是将⽂件mmap之后将⽂件进⾏读取操作,当然最为典型的就是操作系统给我们代劳的可执⾏⽂件的映射。

但是对于⽂件的操作,如果我们不再⼩⼼翼翼,就可能会尝试来修改mmap映射之后的⽂件,但是现在的问题是这个修改是否会写回⽂件,它在什么情况下或者是何时写回⽂件系统中?⼆、映射的系统调⽤mmap在mmap系统调⽤的linux man⼿册说明void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);The flags argument determines whether updates to the mapping are visible to other processes mapping the same region, and whether updates are carried through to the underlying file. This behavior is determined by including exactly one of the following values in flags:MAP_SHARED Share this mapping. Updates to the mapping are visible to other processes that map this file, and are carried throughto the underlying file. The file may not actually be updated until msync(2) or munmap() is called.MAP_PRIVATECreate a private copy-on-write mapping. Updates to the mapping are not visible to other processes mapping the samefile, and are not carried through to the underlying file. It is unspecified whether changes made to the file after themmap() call are visible in the mapped region.这⾥说的很清楚,这⾥的MAP_SHARED和MAP_PRIVATE两个必须有且只能有⼀个,如果没有设置其中的任何⼀个(普通程序员)或者两个都设置(2B程序员),则这个mmap会返回失败。

mmap原理

mmap原理

mmap原理
MMAP原理
MMAP是一种内存映射技术,它可以将文件或其他对象映射到内存中,从而使应用程序可以直接访问文件的内容。

MMAP的工作原理是,当应用程序需要访问文件时,它会将文件映射到内存,然后将文件的内容复制到内存中,这样应用程序就可以直接访问文件的内容了。

当应用程序需要更新文件时,它会将更新后的内容复制到文件中,从而实现对文件的更新。

MMAP具有访问速度快、节约内存空间、可以支持多种类型文件等优点。

MMAP的最大优点是可以大大提高应用程序的访问速度,因为它不用将文件的内容一次性复制到内存中,而是直接将文件映射到内存中,从而可以大大提高访问速度。

MMAP也有一些缺点,比如它不能跨平台使用,而且它也不能处理动态大小的文件,另外它也不能处理文件系统缓存。

MMAP是一种比较有用的内存映射技术,它可以大大提高应用程序的访问速度,但是它也有一些缺点,比如它不能跨平台使用,而且也不能处理动态大小的文件和文件系统缓存。

mmap方法

mmap方法

mmap方法mmap方法:高效处理大文件的神器什么是mmap方法mmap方法(Memory-mapped Files)是一种用于在内存中直接映射文件的技术。

它允许将文件映射到进程的地址空间,从而实现对文件的直接读写操作,而无需通过系统调用来完成。

mmap方法在处理大文件时具有高效性和灵活性,被广泛应用于操作系统、数据库和网络通信等领域。

mmap方法的优势使用mmap方法进行文件操作相对于传统的read和write方法有以下几个优势:1.减少I/O操作:传统的read和write方法需要频繁的磁盘I/O操作,而mmap方法将文件映射到内存中,可以直接在内存中进行读写操作,避免了频繁的磁盘I/O,提高了读写效率。

2.节省内存消耗:mmap方法只需将文件的部分或全部映射到内存中,而不需要将整个文件加载到内存中。

这样可以有效减少内存消耗,特别适用于处理大文件。

3.方便的文件共享:多个进程可以同时对同一个映射文件进行读写操作,实现了方便的文件共享。

这在某些场景下是非常重要的,比如数据库的并发处理。

4.随时同步文件内容:通过修改内存中的映射数据,可以实现对文件内容的实时修改和同步,无需使用繁琐的文件操作接口。

这在某些实时数据处理中非常有用。

mmap方法的使用使用mmap方法可以分为以下几个步骤:1.打开文件:首先通过系统调用打开需要映射的文件,获取文件的文件描述符。

2.确定映射区域:确定需要映射的文件区域以及映射的权限。

可以选择将整个文件映射到内存,也可以只映射部分文件。

3.映射文件到内存:使用mmap函数将文件映射到内存中,得到映射区域的起始地址。

4.进行读写操作:通过修改内存中映射的数据,来实现对文件的读写操作。

可以直接对内存进行操作,无需使用read和write函数。

5.解除映射:在完成文件操作后,需要调用munmap函数来解除文件与内存的映射。

mmap方法的注意事项在使用mmap方法时,需要注意以下几点:•文件大小限制:32位系统对单个文件的映射大小有限制,通常是2GB。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

mmap的用法
mmap(内存映射)是一种在计算机系统中进行文件与主存之间的映射的技术。

它能够将一个文件或者一个设备映射到主存的一部分,使得应用程序可以像访问内存一样访问文件,提供了一种高效的读取和写入数据的方法。

mmap的用法可以分为三个步骤:打开文件、映射文件、访问数据。

下面我将详细介绍每个步骤的使用方法和注意事项。

1. 打开文件:
在使用mmap之前,首先需要通过系统调用打开需要映射的文件。

可以使用open函数来打开文件,如下所示:
int fd = open("filename", O_RDWR); 打开文件,并以可读可写的方式打开
在打开文件时,需要注意以下几点:
- 使用O_RDWR参数可以同时读取和写入文件。

- 文件的访问权限需要注意,通常情况下需要具备可读可写的权限。

- 打开文件后,会返回一个文件描述符fd,后续的操作都需要使用该文件描述符。

2. 映射文件:
打开文件后,下一步是将文件映射到主存。

可以使用mmap函数来完成这个操作,如下所示:
void *addr = mmap(NULL, length, PROT_READ PROT_WRITE,
MAP_SHARED, fd, 0);
mmap函数的参数解释如下:
- 第一个参数是一个建议的映射地址,通常设置为NULL,让系统自动选择合适的地址。

- 第二个参数是映射的长度,可以通过调用stat或fstat函数来获取文件的大小。

- 第三个参数是映射区域的保护方式,PROT_READ表示可读,PROT_WRITE
表示可写。

- 第四个参数是映射区域的共享方式,MAP_SHARED表示与其他所有映射该文件的进程共享内存。

- 第五个参数是文件描述符。

- 第六个参数是文件偏移量,通常设置为0,表示从文件开头开始映射。

在映射文件时,需要注意以下几点:
- 映射的地址最好是页对齐的,否则可能会出现性能问题。

- 映射的长度可以通过调用stat或fstat函数来获取文件的大小。

- 映射的保护方式需要根据实际需求进行设置,一般情况下需要可读可写的权限。

- 映射的共享方式需要根据实际需求进行设置,MAP_SHARED可以实现多个进程之间共享内存。

3. 访问数据:
映射文件成功后,就可以通过访问内存来访问文件的内容了。

由于文件被映射到内存,所以可以直接通过指针访问数据。

例如,可以使用指针来读取或写入文件的内容,如下所示:
char *ptr = (char *)addr; 将映射的地址转换成char类型的指针
读取文件内容
char c = ptr[0]; 读取文件的第一个字节
写入文件内容
ptr[0] = 'A'; 将文件的第一个字节写入为'A'
在访问数据时,需要注意以下几点:
- 使用指针可以直接访问文件的内容,提高了读写文件的效率。

- 这种访问方式类似于使用内存,但是需要注意访问越界的问题。

- 访问文件时,可以按照文件的格式进行读取和写入,比如按字节、按行等。

使用mmap的优点:
1. 高效性:mmap提供了一种将文件映射到内存的方式,避免了频繁的磁盘IO 操作,提高了读写文件的效率。

2. 简单易用:使用mmap可以将文件映射到内存,然后直接通过指针访问文件的内容,类似于访问内存。

相比于使用传统的read和write函数,使用mmap 可以更加方便地进行读写操作。

3. 共享内存:使用MAP_SHARED参数,可以实现多个进程之间共享内存,提高了进程间通信的效率。

使用mmap的注意事项:
1. 对于大文件,映射文件的时候需要确保主存的可用空间足够,否则可能会导致其他程序运行受限。

2. 当文件的大小变化时,需要重新映射文件。

3. 在使用完mmap后,需要使用munmap函数来解除映射关系,释放相关资源。

4. 在并发访问时,需要使用锁机制来避免多个进程同时修改文件的内容,以免出现不一致的情况。

总结:
mmap是一种高效的读写文件的方式,通过将文件映射到内存,可以方便地访问文件的内容。

使用mmap需要首先打开文件,然后将文件映射到内存,最后通过指针访问文件的内容。

在使用mmap时,需要注意一些参数的设置以及一些注意事项,以确保程序的正确运行。

mmap具有高效性、简单易用和共享内存等优点,在实际的应用中得到广泛的应用。

相关文档
最新文档