Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Олифер. Сетевые операционные системы.docx
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
16.5 Mб
Скачать

Дисковый кэш на основе виртуальной памяти

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

В операционных системах Unix на основе кода SVR4 в виртуальном адресном пространстве системы существует специальный сегмент segkmap, на который отображаются данные всех открытых файлов. Диспетчер кэша поддерживает массив структур тар, каждая из которых хранит описание одного отображения. Одно отображение состоит из 8096 последовательных блоков одного файла. Отображаемый файл описывается в структуре smap парой mode/offset, где vnode является указателем на виртуальный дескриптор операции с файлом (см. раздел «Файловые операции» в главе 7), a offset — смещением в файле на диске, начиная с которого отображаются данные файла. Кроме того, в структуре smap указывается виртуальный адрес внутри сегмента segkmap, на который отображаются данные файла.

При выполнении системного вызова read для чтения данных из некоторого открытого файла подсистема ввода-вывода вызывает функцию segmap_getmap диспетчера кэша, которой передается в качестве параметра пара vnode/offset (эти значения берутся из структуры file, описывающей операцию с файлом). Функция segmap_getmap ищет в массиве smap элемент, который содержит требуемую пару vnode/offset. Если такого элемента нет, это значит, что требуемый участок файла еще не отображен на системную память и для нового отображе­ния создается новый элемент smap, а значение виртуального адреса, на который он указывает, возвращается в read. После этого системный вызов read пытается скопировать данные из системной памяти, начиная с указанного адреса, в пользовательский буфер. Так как страницы, содержащей требуемый виртуальный адрес, в оперативной памяти пока нет, то при обращении к памяти возникает страничное прерывание, которое обслуживается соответствующим обработчиком прерываний. В результате блок-ориентированный драйвер читает блоки отсутствующей страницы (а при упреждающей загрузке — и нескольких окружающих ее страниц) с диска и помещает их в системную память. Затем системный вызов read продолжает свою работу, фактически копируя данные в пользовательский буфер. Последующие обращения с помощью вызова read к близкой к прочитанным данным области файла (в пределах 8096 блоков) уже не вызывают нового отображения, а страничные прерывания ведут к загрузке новых блоков файла в кэш по мере необходимости.

На основе таких же принципов работают диспетчеры кэша и в других современных ОС, поддерживающих виртуальную память, например ОС семейства Windows NT, OS/2.