Файлы с отображением в памяти могут использоваться либо для замены доступа для чтения / записи, либо для поддержки одновременного совместного использования. Когда вы используете их для одного механизма, вы получаете и другой.
Вместо того, чтобы искать, писать и читать в файле, вы отображаете его в память и просто получаете доступ к битам там, где вы ожидаете.
Это может быть очень удобно, и в зависимости от интерфейса виртуальной памяти может повысить производительность. Повышение производительности может произойти, потому что операционная система теперь может управлять этим прежним «файловым вводом-выводом» вместе со всем другим программным доступом к памяти и может (теоретически) использовать алгоритмы подкачки и т. Д., Которые она уже использует для поддержки виртуальная память для отдыха вашей программы. Однако это зависит от качества вашей системы виртуальной памяти. Анекдоты, которые я слышал, говорят, что системы виртуальной памяти Solaris и * BSD могут показывать лучшие улучшения производительности, чем системы виртуальных машин Linux - но у меня нет эмпирических данных, подтверждающих это. YMMV.
Параллельность входит в картину, когда вы рассматриваете возможность использования несколькими процессами одного и того же «файла» в отображенной памяти. В модели чтения / записи, если два процесса записывают в одну и ту же область файла, вы можете быть в значительной степени уверены, что одна из данных процесса будет поступать в файл, перезаписывая данные другого процесса. Вы получите одно или другое - но не какое-то странное смешение. Я должен признать, что я не уверен, является ли это поведением, предписанным каким-либо стандартом, но это то, на что вы в значительной степени можете положиться. (На самом деле это хороший вопрос для продолжения!)
В сопоставленном мире, напротив, представьте два процесса, оба «пишущих». Они делают это путем создания «хранилищ памяти», что приводит к тому, что O / S выгружает данные на диск - в конце концов. Но в то же время можно ожидать перекрывающихся записей.
Вот пример. Скажем, у меня есть два процесса, оба пишут 8 байтов со смещением 1024. Процесс 1 пишет «11111111», а процесс 2 пишет «22222222». Если они используют файловый ввод / вывод, вы можете себе представить, что в глубине O / S существует буфер, заполненный 1 с, и буфер, заполненный 2 с, оба направлены в одно и то же место на диске. Один из них собирается добраться туда первым, а второй - вторым. В этом случае выигрывает второй. Однако , если я использую файловый подход с отображением в памяти, процесс 1 отправится в хранилище памяти объемом 4 байта, а затем в другое хранилище памяти объемом 4 байта (предположим, что это не максимальное хранилище памяти размер). Процесс 2 будет делать то же самое. В зависимости от того, когда запущены процессы, вы можете увидеть следующее:
11111111
22222222
11112222
22221111
Решением этой проблемы является использование явного взаимного исключения - что, вероятно, является хорошей идеей в любом случае. В любом случае вы полагались на то, что O / S сделает «правильную вещь» в случае ввода / вывода для файла чтения / записи.
Классифицирующим примитивом взаимного исключения является мьютекс. Для файлов, отображаемых в память, я бы посоветовал вам взглянуть на мьютекс с отображением в памяти, доступный с помощью (например, pthread_mutex_init ().
Редактирование с помощью одной ошибки: при использовании сопоставленных файлов возникает соблазн вставлять указатели на данные в файле, в сам файл (например, связанный список, хранящийся в сопоставленном файле). Вы не хотите этого делать, поскольку файл может отображаться по разным абсолютным адресам в разное время или в разных процессах. Вместо этого используйте смещения в сопоставленном файле.