системный вызов отображенных в память файлов - linux - PullRequest
1 голос
/ 18 ноября 2009

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

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

Ответы [ 2 ]

4 голосов
/ 18 ноября 2009

Когда вы отображаете файл, Linux создает записи в MMU (блок управления памятью). MMU наблюдает за всеми операциями чтения и записи процессора в реальном ОЗУ. Таким образом, он знает, когда вы обращаетесь к частям памяти, которые вернулись mmap(). Чтение частей, которых еще нет в реальном ОЗУ, вызовет сбои страниц. MMU перехватит их и вызовет подпрограмму ядра для загрузки нужной части файла в оперативную память, а затем обновит запись в таблице MMU, так что теперь кажется, что данные расположены по адресу, который дал вам mmap() , Фактически, это будет где-то еще, но MMU сделает это полностью прозрачным.

Когда вы пишете в память, MMU помечает измененные страницы как «грязные». Когда они сбрасываются (поскольку вы обращаетесь к большему количеству файла или потому что вы вызываете munmap()), изменения будут записаны на диск.

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

Все эти эффекты делают mmap настолько эффективным.

3 голосов
/ 18 ноября 2009

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

Возвращаемое значение

В случае успеха, mmap() возвращает указатель на отображенную область. При ошибке значение MAP_FAILED (что есть, (void *) -1) возвращается, и errno установлен соответствующим образом. На успех, munmap() возвращает 0, на ошибка -1, и errno установлено (возможно до EINVAL).

Подробнее см. На странице руководства .

Редактировать Для уточнения:

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

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

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

...