В чем разница между записью в файл и отображенной памятью? - PullRequest
19 голосов
/ 02 сентября 2011

У меня есть следующие вопросы, связанные с обработкой файлов и их отображением (mmap):

  1. Мы знаем, что если мы создадим файл и запишем в него, то в любом случае мы будем записывать в память. Тогда зачем отображать этот файл в память, используя mmap, а затем писать?
  2. Если защита достигается с помощью mmap - PROT_NONE, PROT_READ, PROT_WRITE, то такой же уровень защиты может быть достигнут и с помощью файлов. O_RDONLY, O_RDWR и т. Д. Тогда почему mmap?
  3. Есть ли какое-то особое преимущество, которое мы получаем при отображении файлов в память, а затем при ее использовании? Вместо того, чтобы просто создать файл и записать в него?
  4. Наконец, предположим, что мы mmap файл в память, если мы записываем в эту ячейку памяти, возвращенную mmap, он также одновременно записывает в этот файл?

Пожалуйста, помогите мне ответить на все вопросы.

Заранее большое спасибо.

* РЕДАКТИРОВАТЬ: Обмен файлами между потоками *

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

Но мы знаем, что использование файла означает, что он обязательно находится в основной памяти, тогда почему снова нужно преобразовывать потоки?

Ответы [ 4 ]

16 голосов
/ 02 сентября 2011

Файл, отображаемый в память, фактически частично или полностью отображается в памяти (ОЗУ), тогда как файл, в который вы пишете, записывается в память, а затем записывается на диск. Файл с отображенной памятью извлекается с диска и явно помещается в память для чтения и / или записи. Он остается там, пока вы не удалите его.

Доступ к диску медленнее, поэтому, когда вы записали в файл, он будет записан на диск и больше не будет находиться в ОЗУ, а это значит, что в следующий раз, когда вам понадобится файл, вы, возможно, получите его с диска (медленно), тогда как в отображенных в память файлах вы знаете, что файл находится в ОЗУ, и вы можете получить к нему более быстрый доступ, чем когда он находится на диске.

Кроме того, отображенные в память файлы часто используются в качестве механизма IPC, поэтому два или более процесса могут легко совместно использовать один и тот же файл и читать / записывать его. (используя необходимые механизмы Synnh)

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

EDIT:

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

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

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

2 голосов
/ 02 сентября 2011

1) Вы неправильно поняли системный вызов write (2). write () не записывает, он просто копирует содержимое буфера в цепочку буферов ОС и помечает его как грязный. Один из потоков ОС (bdflush IIRC) соберет эти буферы, запишет их на диск и поиграет с некоторыми флагами. потом. С mmap вы напрямую обращаетесь к буферу ОС (но если вы измените его содержимое, оно тоже будет помечено как грязное)

2) Речь идет не о защите, а об установке флагов в записях таблицы.

3) вы избегаете двойной буферизации. Также вы можете обращаться к файлу в терминах символов вместо блоков, что иногда более практично

4) Это системные буферы (подключенные к вашему адресному пространству), которые вы использовали. Система может записывать или не записывать ее части на диск.

5) Если потоки принадлежат одному процессу и совместно используют таблицы страниц и адресное пространство, да.

1 голос
/ 02 сентября 2011
  1. Одной из причин может быть то, что у вас есть (унаследованный) код, настроенный для записи в буфер данных, а затем этот буфер записывается в файл за один раз в конце. В этом случае использование mmap сохранит хотя бы одну копию данных, поскольку ОС может напрямую записать буфер на диск. Пока речь идет только о записи в файл, я не могу (пока) представить какие-либо другие причины, по которым вы захотите использовать mmap.

  2. Нет, защита здесь не актуальна, я бы сказал.

  3. Это может сохранить одну или две копии данных, например, из. буфер приложения в буфер libc в буфер ОС, см. пункт 1. Это может повлиять на производительность при записи больших объемов данных.

  4. Нет. Насколько я знаю, ОС может свободно записывать данные в любое удобное время, если данные записаны на диск после вызова msync или munmap в этой области памяти. (И для большинства файлов он, вероятно, ничего не будет записывать в течение большей части времени по причинам производительности: запись целого блока на диск из-за того, что один байт был изменен, довольно дорогая, в частности, если ожидается, что гораздо больше модификаций в блок произойдет в ближайшее время.)

0 голосов
/ 02 сентября 2011

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

...