Понятие о файлах, отображаемых в память (memory mapped файлах). Системные вызовы mmap(), munmap()
Как уже говорилось, с помощью системного вызова open() операционная система отображает файл из пространства имен в дисковое пространство файловой системы, подготавливая почву для осуществления других операций. С появлением концепции виртуальной памяти, которая рассматривалась в лекции 9, когда физические размеры памяти перестали играть роль сдерживающего фактора в развитии вычислительных систем, стало возможным отображать файлы непосредственно в адресное пространство процессов. Иными словами, появилась возможность работать с файлами как с обычной памятью, заменив выполнение базовых операций над ними с помощью системных вызовов на использование операций обычных языков программирования. Файлы, чье содержимое отображается непосредственно в адресное пространство процессов, получили название файлов, отображаемых в память, или, по-английски, memory mapped файлов (см. лекцию 10). Надо отметить, что такое отображение может быть осуществлено не только для всего файла в целом, но и для его части.
С точки зрения программиста работа с такими файлами выглядит следующим образом:
- Отображение файла из пространства имен в адресное пространство процесса происходит в два этапа: сначала выполняется отображение в дисковое пространство, а уже затем из дискового пространства в адресное. Поэтому вначале файл необходимо открыть, используя обычный системный вызов open().
- Вторым этапом является отображение файла целиком или частично из дискового пространства в адресное пространство процесса. Для этого используется системный вызов mmap(). Файл после этого можно и закрыть, выполнив системный вызов close(), так как необходимую информацию о расположении файла на диске мы уже сохранили в других структурах данных при вызове mmap().
Системный вызов mmap() Прототип системного вызова #include <sys/types.h> #include <unistd.h> #include <sys/mman.h> void *mmap (void *start, size_t length, int prot, int flags, int fd, off_t offset); Описание системного вызова Системный вызов mmap служит для отображения предварительно открытого файла (например, с помощью системного вызова open()) в адресное пространство вычислительной системы. После его выполнения файл может быть закрыт (например, системным вызовом close()), что никак не повлияет на дальнейшую работу с отображенным файлом. Настоящее описание не является полным описанием системного вызова, а предназначено только для использования в рамках данного курса. Для получения полной информации обращайтесь к UNIX Manual. Параметр fd является файловым дескриптором для файла, который мы хотим отобразить в адресное пространство (т.е. значением, которое вернул системный вызов open()). Ненулевое значение параметра start может использоваться только очень квалифицированными системными программистами, поэтому мы в семинарах будем всегда полагать его равным значению NULL, позволяя операционной системе самой выбрать начало области адресного пространства, в которую будет отображен файл. В память будет отображаться часть файла, начиная с позиции внутри его, заданной значением параметра offset – смещение от начала файла в байтах, и длиной, равной значению параметра length (естественно, тоже в байтах). Значение параметра length может и превышать реальную длину от позиции offset до конца существующего файла. На поведении системного вызова это никак не отразится, но в дальнейшем при попытке доступа к ячейкам памяти, лежащим вне границ реального файла, возникнет сигнал SIGBUS (реакция на него по умолчанию – прекращение процесса с образованием core файла). Параметр flags определяет способ отображения файла в адресное пространство. В рамках нашего курса мы будем использовать только два его возможных значения: MAP_SHARED и MAP_PRIVATE. Если в качестве его значения выбрано MAP_SHARED, то полученное отображение файла впоследствии будет использоваться и другими процессами, вызвавшими mmap для этого файла с аналогичными значениями параметров, а все изменения, сделанные в отображенном файле, будут сохранены во вторичной памяти. Если в качестве значения параметра flags указано MAP_PRIVATE, то процесс получает отображение файла в свое монопольное распоряжение, но все изменения в нем не могут быть занесены во вторичную память (т.е., проще говоря, не сохранятся). Параметр prot определяет разрешенные операции над областью памяти, в которую будет отображен файл. В качестве его значения мы будем использовать значения PROT_READ (разрешено чтение), PROT_WRITE (разрешена запись) или их комбинацию через операцию "побитовое или" – "|". Необходимо отметить две существенные особенности системного вызова, связанные с этим параметром:
Возвращаемое значение При нормальном завершении системный вызов возвращает начальный адрес области памяти, в которую отображен файл (или его часть), при возникновении ошибки – специальное значение MAP_FAILED. |
ul>
Системный вызов munmap Прототип системного вызова #include <sys/types.h> #include <unistd.h> #include <sys/mman.h> int munmap (void *start, size_t length); Описание системного вызова Системный вызов munmap служит для прекращения отображения memory mapped файла в адресное пространство вычислительной системы. Если при системном вызове mmap() было задано значение параметра flags, равное MAP_SHARED, и в отображении файла была разрешена операция записи (в параметре prot использовалось значение PROT_WRITE), то munmap синхронизирует содержимое отображения с содержимым файла во вторичной памяти. После его выполнения области памяти, использовавшиеся для отображения файла, становятся недоступны текущему процессу. Параметр start является адресом начала области памяти, выделенной для отображения файла, т.е. значением, которое вернул системный вызов mmap(). Параметр length определяет ее длину, и его значение должно совпадать со значением соответствующего параметра в системном вызове mmap(). Возвращаемое значение При нормальном завершении системный вызов возвращает значение 0, при возникновении ошибки – значение -1. |