В чем разница между записью файла и отображаемой памятью?

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

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

Просьба помочь мне ответить на все запросы.

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

* EDIT: совместное использование файлов между потоками *

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

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

Ответы

Ответ 1

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

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

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

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

EDIT:

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

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

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

Ответ 2

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

2) Речь идет не о защите, а о настройке флагов в pagetable entries.

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

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

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

Ответ 3

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

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

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

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

Ответ 4

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