掌握聚合最新动态了解行业最新趋势
API接口,开发服务,免费咨询服务

mmap内存映射详解(定义、原理、作用、特点、实例)

mmap是一种在Unix/Linux系统下用于将文件或其他对象映射到进程地址空间的技术。它使得文件内容可以被当作内存进行访问,从而大大提高了文件读写的效率。本文将详细解释mmap的定义、原理、作用、特点以及实例代码,旨在为读者提供全面而深入的理解。

一、mmap的定义

mmap(memory map)即内存映射,是一种将一个文件或者其它对象映射到进程的地址空间的技术。简单来说,mmap可以使磁盘文件的内容看起来像是内存中的一个数组,使得进程能够通过指针直接操作这片内存,而无需调用read、write等系统调用。这种机制不仅提高了文件操作的速度,还简化了程序对文件内容的访问方式。

二、mmap的原理

mmap内存映射的实现过程可以分为三个阶段:

  1. 启动映射过程:

在用户进程的虚拟地址空间中,寻找一段空闲的满足要求的连续虚拟地址。为此虚拟区分配一个vm_area_struct结构,并初始化该结构的各个域,然后将新建的虚拟区结构插入进程的虚拟地址区域链表或树中。

  1. 建立文件物理地址和进程虚拟地址的映射关系:

通过系统调用函数mmap(不同于用户空间库函数),在文件描述符表中查找对应的文件描述符,并通过文件结构体链接到file_operations模块,最终定位到文件磁盘物理地址。通过remap_pfn_range函数建立页表,完成文件地址和虚拟地址区域的映射关系。此时,这片虚拟地址并没有任何数据关联到主存中。

  1. 访问映射空间引发缺页异常,实现文件内容到物理内存的拷贝:

当进程发起读或写操作时,发现这段地址并不在物理页面上,因此引发缺页异常。内核进行一系列判断后,发起请求调页过程,先在交换缓存空间中寻找需要的内存页,如果没有则从磁盘中装入数据。之后,进程即可对这片主存进行读写操作,如果写操作改变了其内容,系统会在一段时间后自动回写脏页面到对应磁盘地址。

三、mmap的作用

  1. 提高文件操作效率:通过内存映射,文件的读写操作可以直接在内存中进行,避免了频繁的系统调用,大大提高了性能。

  2. 简化文件访问方式:文件内容可以被当作内存进行访问,程序可以通过指针直接操作文件数据,简化了代码逻辑。

  3. 实现文件共享:多个进程可以映射同一个文件到各自的地址空间,通过对这片内存的访问实现进程间通信和数据共享。

  4. 支持匿名内存映射:可以将匿名内存映射用于具有亲缘关系的进程之间(如父子进程)共享数据,避免使用特殊文件提供的共享内存。

四、mmap的特点

  1. 高效性:内存映射使文件读写操作直接在内存中进行,减少了系统调用开销,提高了性能。

  2. 灵活性:可以将普通文件、设备文件甚至匿名内存映射到进程地址空间,满足不同场景的需求。

  3. 透明性:对程序员而言,文件内容看起来像是内存的一部分,无需关心底层的磁盘操作细节。

  4. 可共享性:多个进程可以映射同一个文件,通过内存映射实现进程间通信和数据共享。

  5. 延迟写入:修改过的脏页面并不会立即更新回文件中,而是有一段时间的延迟,可以通过调用msync函数强制同步。

五、mmap的实例

以下是一个简单的mmap示例代码,演示如何将一个文件映射到内存并进行读写操作。

#include 
#include 
#include 
#include 
#include 
#include 
int main() {
    const char *filepath = "example.txt";
    const size_t length = 4096;
    // 打开文件
    int fd = open(filepath, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }
    // 调整文件大小
    if (ftruncate(fd, length) == -1) {
        perror("ftruncate");
        close(fd);
        exit(EXIT_FAILURE);
    }
    // 创建内存映射 PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (map == MAP_FAILED) {
        perror("mmap");
        close(fd);
        exit(EXIT_FAILURE);
    }
    // 向内存映射区域写入数据
    const char *message = "Hello, mmap!";
    snprintf(map + (length / 2), length - (length / 2), "%s", message);
    // 同步内存映射区域到文件
    if (msync(map, length, MS_SYNC) == -1) {
        perror("msync");
        munmap(map, length);
        close(fd);
        exit(EXIT_FAILURE);
    }
    // 读取内存映射区域的数据并打印
    printf("Read from memory-mapped file: %s
", (char *)map + (length / 2));
    // 解除内存映射并关闭文件
    if (munmap(map, length) == -1) {
        perror("munmap");
        close(fd);
        exit(EXIT_FAILURE);
    }
    close(fd);
    return 0;
}

上述代码展示了如何使用mmap函数将一个文件映射到内存,进行读写操作,并将修改后的数据同步回磁盘。具体步骤如下:
1. 打开文件并调整其大小以适应映射区域。
2. 使用mmap函数创建内存映射。
3. 向内存映射区域写入数据。
4. 使用msync函数同步内存映射区域到文件。
5. 读取内存映射区域的数据并打印。
6. 解除内存映射并关闭文件。

mmap是一种强大的技术,通过将文件或其他对象映射到进程的地址空间,实现了高效的文件操作和灵活的内存管理。它不仅提高了性能,还简化了文件访问方式,支持文件共享和匿名内存映射。然而,使用mmap也需要注意正确处理错误情况和同步问题,以确保数据一致性和程序稳定性。

声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com

  • 涉农贷款地址识别

    涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。

    涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。

  • 人脸四要素

    根据给定的手机号、姓名、身份证、人像图片核验是否一致

    根据给定的手机号、姓名、身份证、人像图片核验是否一致

  • 个人/企业涉诉查询

    通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。

    通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。

  • IP反查域名

    IP反查域名是通过IP查询相关联的域名信息的功能,它提供IP地址历史上绑定过的域名信息。

    IP反查域名是通过IP查询相关联的域名信息的功能,它提供IP地址历史上绑定过的域名信息。

  • 人脸卫士

    结合权威身份认证的精准人脸风险查询服务,提升人脸应用及身份认证生态的安全性。人脸风险情报库,覆盖范围广、准确性高,数据权威可靠。

    结合权威身份认证的精准人脸风险查询服务,提升人脸应用及身份认证生态的安全性。人脸风险情报库,覆盖范围广、准确性高,数据权威可靠。

0512-88869195
数 据 驱 动 未 来
Data Drives The Future