内存映射详细介绍

目录

一、相关概念

二、代码样例

三、与 Direct IO 的不同


一、相关概念

        内存映射是一种常见的操作系统技术,它允许程序将磁盘文件映射到进程的地址空间中,从而使得程序可以像访问内存一样访问文件。这种技术可以极大地简化文件的读写操作,并且可以提高程序的性能。

        内存映射是通过将磁盘文件映射到进程的地址空间中来实现的。在这种方式下,操作系统会将文件的某个区域映射到进程的虚拟地址空间中,从而使得程序可以直接访问这个区域的数据。

        在 Linux 系统中,内存映射是通过调用 mmap() 函数来实现的。这个函数的原型如下:

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
/*
addr:指定映射的起始地址。如果为 NULL,则由操作系统自动选择一个地址。

length:指定映射的长度。

prot:指定映射区域的保护方式。可以是以下几种值的组合:
    PROT_READ:可读。
    PROT_WRITE:可写。
    PROT_EXEC:可执行。

flags:指定映射区域的标志。可以是以下几种值的组合:
    MAP_SHARED:与其他进程共享映射区域。
    MAP_PRIVATE:不与其他进程共享映射区域。
    MAP_FIXED:指定映射区域的起始地址。如果指定了这个标志,则 addr 参数必须为非 NULL。
    MAP_ANONYMOUS:不映射任何文件,而是映射一段匿名的内存区域。

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

offset:指定要映射的文件的偏移量。
*/

二、代码样例

         下面代码的作用是读取一个文件的内容,并将其输出到屏幕上。然后,它将文件的内容修改为 "Hello, world!",并将修改后的内容写回到磁盘中。

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

int main(int argc, char *argv[]) {
    int fd;
    char *addr;
    struct stat sb;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <file>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    fd = open(argv[1], O_RDWR);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    if (fstat(fd, &sb) == -1) {
        perror("fstat");
        exit(EXIT_FAILURE);
    }

    addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (addr == MAP_FAILED) {
        perror("mmap");
        exit(EXIT_FAILURE);
    }

    printf("The file content is: %s\n", addr);

    strcpy(addr, "Hello, world!");

    if (msync(addr, sb.st_size, MS_SYNC) == -1) {
        perror("msync");
        exit(EXIT_FAILURE);
    }

    if (munmap(addr, sb.st_size) == -1) {
        perror("munmap");
        exit(EXIT_FAILURE);
    }

    close(fd);

    return 0;
}

三、与 Direct IO 的不同

        内存映射和 Direct IO 都是用来提高文件读写性能的技术,但它们之间有一些不同。

        首先,内存映射是将文件映射到进程的地址空间中,而 Direct IO 是直接使用文件描述符进行读写操作。因此,内存映射可以充分利用虚拟内存系统的优势,而 Direct IO 则可以避免缓存的影响。

        其次,内存映射可以实现文件的共享访问,而 Direct IO 则不行。这是因为 Direct IO 会绕过文件系统缓存,而文件系统缓存是用来实现文件共享访问的。

        最后在内存映射中,修改过的数据会被缓存在内存中,并不会立即写回到磁盘中。如果需要将数据写回到磁盘中,可以使用 msync() 函数或者 munmap() 函数来实现。而 Direct IO 是可以直接将数据写入磁盘的。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我要出家当道士

打赏是不可能,这辈子都不可能

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值