• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

内存映射详细

武飞扬头像
我要出家当道士
帮助1

目录

一、相关概念

二、代码样例

三、与 Direct IO 的不同


一、相关概念

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

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

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

  1.  
    void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
  2.  
    /*
  3.  
    addr:指定映射的起始地址。如果为 NULL,则由操作系统自动选择一个地址。
  4.  
     
  5.  
    length:指定映射的长度。
  6.  
     
  7.  
    prot:指定映射区域的保护方式。可以是以下几种值的组合:
  8.  
    PROT_READ:可读。
  9.  
    PROT_WRITE:可写。
  10.  
    PROT_EXEC:可执行。
  11.  
     
  12.  
    flags:指定映射区域的标志。可以是以下几种值的组合:
  13.  
    MAP_SHARED:与其他进程共享映射区域。
  14.  
    MAP_PRIVATE:不与其他进程共享映射区域。
  15.  
    MAP_FIXED:指定映射区域的起始地址。如果指定了这个标志,则 addr 参数必须为非 NULL。
  16.  
    MAP_ANONYMOUS:不映射任何文件,而是映射一段匿名的内存区域。
  17.  
     
  18.  
    fd:指定要映射的文件描述符。
  19.  
     
  20.  
    offset:指定要映射的文件的偏移量。
  21.  
    */
学新通

二、代码样例

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

  1.  
    #include <stdio.h>
  2.  
    #include <stdlib.h>
  3.  
    #include <string.h>
  4.  
    #include <sys/mman.h>
  5.  
    #include <sys/stat.h>
  6.  
    #include <fcntl.h>
  7.  
    #include <unistd.h>
  8.  
     
  9.  
    int main(int argc, char *argv[]) {
  10.  
    int fd;
  11.  
    char *addr;
  12.  
    struct stat sb;
  13.  
     
  14.  
    if (argc != 2) {
  15.  
    fprintf(stderr, "Usage: %s <file>\n", argv[0]);
  16.  
    exit(EXIT_FAILURE);
  17.  
    }
  18.  
     
  19.  
    fd = open(argv[1], O_RDWR);
  20.  
    if (fd == -1) {
  21.  
    perror("open");
  22.  
    exit(EXIT_FAILURE);
  23.  
    }
  24.  
     
  25.  
    if (fstat(fd, &sb) == -1) {
  26.  
    perror("fstat");
  27.  
    exit(EXIT_FAILURE);
  28.  
    }
  29.  
     
  30.  
    addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  31.  
    if (addr == MAP_FAILED) {
  32.  
    perror("mmap");
  33.  
    exit(EXIT_FAILURE);
  34.  
    }
  35.  
     
  36.  
    printf("The file content is: %s\n", addr);
  37.  
     
  38.  
    strcpy(addr, "Hello, world!");
  39.  
     
  40.  
    if (msync(addr, sb.st_size, MS_SYNC) == -1) {
  41.  
    perror("msync");
  42.  
    exit(EXIT_FAILURE);
  43.  
    }
  44.  
     
  45.  
    if (munmap(addr, sb.st_size) == -1) {
  46.  
    perror("munmap");
  47.  
    exit(EXIT_FAILURE);
  48.  
    }
  49.  
     
  50.  
    close(fd);
  51.  
     
  52.  
    return 0;
  53.  
    }
学新通

三、与 Direct IO 的不同

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

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

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

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

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgggefj
系列文章
更多 icon
同类精品
更多 icon
继续加载