Прочитайте принцип mmap в одной статье

Linux

существует"Узнайте о технологии нулевого копирования в одной статье, мы представили零拷贝技术Принцип, и мы знаем, чтоmmapЭто также реализация технологии нулевого копирования. В этой статье мы в основном знакомимmmapпринцип.

Во-первых, традиционное чтение документов

Вообще говоря, изменение содержимого файла требует следующих трех шагов:

  • Считайте содержимое файла в память.
  • Измените содержимое памяти.
  • Запишите данные из памяти в файл.

Процесс показан на рисунке 1:

read-write.png

Если вы используете код для реализации вышеуказанного процесса, код выглядит следующим образом:

read(fd, buf, 1024);  // 读取文件的内容到buf
...                   // 修改buf的内容
write(fd, buf, 1024); // 把buf的内容写入到文件

Как видно из рисунка 1,页缓存(page cache)Является средним слоем при чтении и записи файлов, ядро ​​использует页缓存Связан с блоком данных файла. Поэтому, когда приложение читает и записывает файл, фактическая операция页缓存.

2. Используйте mmap для чтения и записи файлов

Из традиционного процесса чтения и записи файлов мы можем обнаружить, что есть место для оптимизации: если вы можете читать и писать прямо в пользовательском пространстве页缓存, то можно избежать页缓存Процесс копирования данных в буферы пользовательского пространства.

Итак, существует ли такая технология, которая может достичь вышеупомянутого? Ответ да, этоmmap.

использоватьmmapСистемный вызов может отображать (привязывать) адрес виртуальной памяти пользовательского пространства к файлу, а операции чтения и записи для сопоставленного адреса виртуальной памяти такие же, как операции чтения и записи для файла. Принцип показан на рисунке 2:

mmap.png

Как мы упоминали ранее, чтение и запись файлов должны проходить через页缓存,такmmapЭто файл, который отображается页缓存, а не сам файл на диске. так какmmapфайл отображается页缓存, значит проблема синхронизации, т.е.页缓存Когда данные будут синхронизированы на диск.

Ядро Linux не активноmmapнанесен на карту页缓存Синхронизируется с диском, но требует активного запуска пользователем. СинхронизироватьmmapСуществует 4 случая отображения памяти на диск:

  • перечислитьmsyncФункция активно выполняет синхронизацию данных (активна).
  • перечислитьmunmapКогда функция отменяет сопоставление файла (активно).
  • Когда процесс завершается (пассивный).
  • Когда система выключается (пассивная).

3. Как использовать ммап

Ниже мы расскажем, как использоватьmmap,mmapПрототип функции выглядит следующим образом:

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

Давайте представимmmapНазначение каждого параметра функции:

  • addr: указывает отображаемый адрес виртуальной памяти, для которого можно установить значение NULL, чтобы позволить ядру Linux автоматически выбирать соответствующий адрес виртуальной памяти.

  • length: Длина карты.

  • prot: Режим защиты отображаемой памяти, необязательные значения следующие:

    • PROT_EXEC: может быть выполнено.
    1. PROT_READ: Можно прочитать.
    2. PROT_WRITE: Можно написать.
    3. PROT_NONE: Не доступный.
  • flags: Указывает тип сопоставления.Часто используемые необязательные значения:

    • MAP_FIXED: использовать указанный начальный адрес виртуальной памяти для сопоставления.
    1. MAP_SHARED: Совместное использование пространства сопоставления со всеми другими процессами, которые сопоставляются с этим файлом (может быть реализована общая память).
    2. MAP_PRIVATE: создать частное пространство сопоставления с копированием при записи.
    3. MAP_LOCKED: Блокирует страницы в отображаемой области, чтобы предотвратить их выгрузку из памяти.
    4. ...
  • fd: Дескриптор файла для сопоставления.

  • offset: Смещение файла (откуда начать сопоставление в файле).

ВведениеmmapПосле прототипа функции мы теперь познакомимся с тем, как ее использовать, на простом примере.mmap:

int fd = open(filepath, O_RDWR, 0644);                           // 打开文件
void *addr = mmap(NULL, 8192, PROT_WRITE, MAP_SHARED, fd, 4096); // 对文件进行映射

В приведенном выше примере мы сначала передаемopenфункция, чтобы открыть файл для чтения и записи, затем передатьmmapФункция отображает файл следующим образом:

  • addrПараметр имеет значение NULL, что означает, что операционная система автоматически выбирает соответствующий адрес виртуальной памяти для сопоставления.
  • lengthУстановка параметра на 8192 означает, что отображаемая область имеет размер 2 страницы памяти (одна страница памяти имеет размер 4 КБ).
  • protпараметр установлен наPROT_WRITEУказывает, что отображаемая область памяти доступна для чтения и записи.
  • flagsпараметр установлен наMAP_SHAREDУказывает общую область сопоставления.
  • fdПараметр задает дескриптор открытого файла.
  • offsetПараметр установлен на 4096, чтобы начать сопоставление с 4096 в файле.

mmapФункция вернет сопоставленный адрес памяти, мы можем читать и записывать файл через этот адрес памяти. Мы показываем структуру приведенного выше примера в ядре на рисунке 3:

mmap-address.png

4. Резюме

Эта статья в основном знакомитmmapПринцип и использование, благодаря этой статье мы можем узнать, использоватьmmapПри чтении и записи файлов количество копий памяти может быть уменьшено, а количество системных вызовов уменьшено, что повышает эффективность операций чтения и записи файлов.

Так как ядро ​​активно не синхронизируетсяmmapДанные в отображенной области памяти, поэтому потеря данных может произойти в некоторых особых случаях (например, при сбое питания). Во избежание потери данных используйтеmmapможет быть активно вызван, когда это уместноmsyncфункция синхронизации данных в отображаемой области памяти.