Как уже говорилось, с помощью системного вызова open() операционная система отображает файл из пространства имен в дисковое пространство файловой системы, подготавливая почву для осуществления других операций. С появлением концепции виртуальной памяти, которая рассматривалась в лекции 9, когда физические размеры памяти перестали играть роль сдерживающего фактора в развитии вычислительных систем, стало возможным отображать файлы непосредственно в адресное пространство процессов. Иными словами, появилась возможность работать с файлами как с обычной памятью, заменив выполнение базовых операций над ними с помощью системных вызовов на использование операций обычных языков программирования. Файлы, чье содержимое отображается непосредственно в адресное пространство процессов, получили название файлов, отображаемых в память, или, по-английски, memory mapped файлов (см. лекцию 10). Надо отметить, что такое отображение может быть осуществлено не только для всего файла в целом, но и для его части.
С точки зрения программиста работа с такими файлами выглядит следующим образом:
Системный вызов 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. |