существует"Узнайте о технологии нулевого копирования в одной статье, мы представили零拷贝技术Принцип, и мы знаем, чтоmmapЭто также реализация технологии нулевого копирования. В этой статье мы в основном знакомимmmapпринцип.
Во-первых, традиционное чтение документов
Вообще говоря, изменение содержимого файла требует следующих трех шагов:
- Считайте содержимое файла в память.
- Измените содержимое памяти.
- Запишите данные из памяти в файл.
Процесс показан на рисунке 1:
Если вы используете код для реализации вышеуказанного процесса, код выглядит следующим образом:
read(fd, buf, 1024); // 读取文件的内容到buf
... // 修改buf的内容
write(fd, buf, 1024); // 把buf的内容写入到文件
Как видно из рисунка 1,页缓存(page cache)Является средним слоем при чтении и записи файлов, ядро использует页缓存Связан с блоком данных файла. Поэтому, когда приложение читает и записывает файл, фактическая операция页缓存.
2. Используйте mmap для чтения и записи файлов
Из традиционного процесса чтения и записи файлов мы можем обнаружить, что есть место для оптимизации: если вы можете читать и писать прямо в пользовательском пространстве页缓存, то можно избежать页缓存Процесс копирования данных в буферы пользовательского пространства.
Итак, существует ли такая технология, которая может достичь вышеупомянутого? Ответ да, этоmmap.
использоватьmmapСистемный вызов может отображать (привязывать) адрес виртуальной памяти пользовательского пространства к файлу, а операции чтения и записи для сопоставленного адреса виртуальной памяти такие же, как операции чтения и записи для файла. Принцип показан на рисунке 2:
Как мы упоминали ранее, чтение и запись файлов должны проходить через页缓存,так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: может быть выполнено.
-
PROT_READ: Можно прочитать. -
PROT_WRITE: Можно написать. -
PROT_NONE: Не доступный.
-
-
flags: Указывает тип сопоставления.Часто используемые необязательные значения:-
MAP_FIXED: использовать указанный начальный адрес виртуальной памяти для сопоставления.
-
MAP_SHARED: Совместное использование пространства сопоставления со всеми другими процессами, которые сопоставляются с этим файлом (может быть реализована общая память). -
MAP_PRIVATE: создать частное пространство сопоставления с копированием при записи. -
MAP_LOCKED: Блокирует страницы в отображаемой области, чтобы предотвратить их выгрузку из памяти. - ...
-
-
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:
4. Резюме
Эта статья в основном знакомитmmapПринцип и использование, благодаря этой статье мы можем узнать, использоватьmmapПри чтении и записи файлов количество копий памяти может быть уменьшено, а количество системных вызовов уменьшено, что повышает эффективность операций чтения и записи файлов.
Так как ядро активно не синхронизируетсяmmapДанные в отображенной области памяти, поэтому потеря данных может произойти в некоторых особых случаях (например, при сбое питания). Во избежание потери данных используйтеmmapможет быть активно вызван, когда это уместноmsyncфункция синхронизации данных в отображаемой области памяти.