linux上的mmap是什么

发布于:2024-05-07 ⋅ 阅读:(19) ⋅ 点赞:(0)

左手编程,右手年华。大家好,我是一点,关注我,带你走入编程的世界。

公众号:一点sir,关注领取编程资料

mmap是什么

mmap 是一个在 Unix 和类 Unix 系统中的 POSIX 标准系统调用,用于将一个文件或者其他对象映射到进程地址空间中的内存区域。简而言之,mmap 允许一个程序将磁盘上的文件内容直接映射到内存中,从而可以像访问普通内存一样访问文件内容。

mmap函数解释

mmap 函数的原型如下:

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

参数说明:

  • addr:希望映射到的内存地址。通常设为 NULL,让系统自行选择映射区域的地址。
  • length:映射的长度,通常为文件大小。
  • prot:映射区域的保护方式,可以是 PROT_EXEC(可执行)、PROT_READ(可读)、PROT_WRITE(可写)、PROT_NONE(不可访问)的组合。
  • flags:控制映射区域的特性,如 MAP_SHARED(对映射区域的修改会写回文件,允许多个进程共享映射)、MAP_PRIVATE(私有副本,修改不写回文件)等。
  • fd:被映射文件的文件描述符。
  • offset:文件中的偏移量,通常为文件系统中分配单元的大小(如 4096 字节)。

mmap 返回值:

  • 成功时,返回指向映射区域的指针。
  • 失败时,返回 MAP_FAILED(通常是 (void *)-1),并设置 errno 以指示错误。

使用 mmap 后,通常还需要使用 munmap 来撤销映射,释放内存资源。

int munmap(void *addr, size_t length);

参数 addrmmap 返回的地址,length 是映射的长度。munmap 函数在成功时返回 0,在失败时返回 -1,并设置 errno

示例说明

这里我用一个使用 mmap 的简单例子,它展示了如何在C语言中使用 mmap 将文件映射到内存中,并对文件内容进行读取和写入操作。

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    // 打开一个文件,这里我们创建一个新文件
    int fd = open("example.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    // 文件大小,这里我们设置为 10 个页面的大小
    size_t length = 10 * sysconf(_SC_PAGESIZE);

    // 调用 mmap
    void *mapped_memory = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (mapped_memory == MAP_FAILED) {
        perror("mmap");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 写入一些数据到映射的内存区域
    for (size_t i = 0; i < length; ++i) {
        ((char *)mapped_memory)[i] = (char)('A' + (i % 26));
    }

    // 等待用户输入,以便查看映射的内容
    printf("Press Enter to unmap and exit...\n");
    getchar();

    // 撤销映射
    if (munmap(mapped_memory, length) == -1) {
        perror("munmap");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 关闭文件描述符
    if (close(fd) == -1) {
        perror("close");
        exit(EXIT_FAILURE);
    }

    return 0;
}

我们首先打开(或创建)一个名为 "example.txt" 的文件,然后获取系统的页面大小,并将其乘以10以确定映射的长度。映射成功后,我们可以像操作普通内存一样操作这个映射区域。在这个例子中,我们用大写字母 'A' 到 'Z' 填充映射的内存。然后,程序暂停,等待用户按下回车键,之后使用 munmap 撤销映射,并关闭文件描述符。

这是一个非常简单的例子,但是基本上对于mmap的用法做了大概的说明。

mmap的优点

使用 mmap 的主要优点包括:

  1. 性能:对映射区域的修改最终会回写到文件中,这比传统的 read 和 write 系统调用通常更高效,特别是对于大文件和/或多个连续的 read/write 操作。

  2. 简化编程模型:通过 mmap,程序员可以使用指针算术直接操作文件内容,而不需要编写额外的缓冲区管理代码。

  3. 共享内存mmap 可以用来创建或访问共享内存区域,这对于进程间通信(IPC)非常有用。

  4. 自动管理:操作系统负责管理映射区域的内存,当映射的文件被关闭或程序结束时,映射会自动撤销。