- •Курс лекций по дисциплине "операционные системы"
- •Учебные вопросы лекции
- •Содержание лекции
- •1. Компоненты системы ввода-вывода
- •1.1. Задачи ос по управлению файлами и устройствами
- •Динамическая загрузка и выгрузка драйверов
- •Поддержка нескольких файловых систем
- •1.2. Многослойная модель подсистемы ввода-вывода
- •2. Обработка ввода-вывода
2. Обработка ввода-вывода
В свое время ОС UNIX определила новый, упрощенный подход к вводу-выводу. В его рамках все считываемые или записываемые данные рассматриваются просто как поток байтов, направляемый в виртуальные файлы, которые представляются файловыми дескрипторами. Виртуальный файл (virtual file) обозначает любой источник или приемник ввода-вывода, работа с которым идет так, как если бы он был файлом. ОС определяет, является ли "файл" консольным терминалом, каналом или настоящим файлом на диске, и направляет данные в нужное место.
В Windows NT программы также осуществляют ввод-вывод в виртуальные файлы, манипулируя ими посредством описателей файла (file handles). Концепция описателя файла не нова, но в исполнительной системе NT описатель файла фактически ссылается на файловый объект (file object) исполнительной системы. Все возможные источники или приемники ввода-вывода представлены файловыми объектами. Потоки пользовательского режима вызывают базовые сервисы файлового объекта NT для чтения из файла, записи в файл и выполнения других операций. Диспетчер ввода-вывода динамически преобразует эти запросы к виртуальным файлам в запросы к настоящим файлам, каталогам файлов, физическим устройствам, каналам, сетям, почтовым ящикам и любым другим местам назначения, которые только могут возникнуть в будущем.
Запросы ввода-вывода проходят несколько четко определенных этапов обработки. Эти этапы различаются, в зависимости от того, направлен ли запрос к устройству, управляемому однослойным драйвером, или он проходит через многослойный драйвер. Дальнейшие различия в обработке определяются заданным типом ввода-вывода — синхронным или асинхронным.
Большинство запросов начинают свой путь одинаково. После открытия описателя файла приложение вызывает некоторую процедуру ввода-вывода. Эта процедура обычно предоставляется библиотекой языка программирования или подсистемой среды. В любом случае подсистема Win32 (или DLL) вызывает базовую функцию системы ввода-вывода. В ответ оно получает (в той или иной форме) описатель файлового объекта исполнительной системы NT. Например, когда приложение Win32 вызывает функцию fopen(), библиотека С обращается к функции API Win32 CreateFileQ, которая, в свою очередь, вызывает объектный сервис ввода-вывода NT. Диспетчер ввода-вывода открывает файловый объект и возвращает описатель объекта библиотеке С, которая передает его прикладной программе (рис. 2).
Источники и приемники ввода-вывода представлены в виде объектов, так как они удовлетворяют определению объекта Windows NT: это системные ресурсы, которые могут совместно использоваться потоками двух или более процессов пользовательского режима. Файловые объекты, как и другие объекты, имеют иерархические имена, охраняются объектной защитой, поддерживают синхронизацию и обрабатываются объектными сервисами.
Рис. 2. Открытие файлового объекта
Открывая файл, пользователь задает имя файла и необходимый тип доступа — обычно чтение, запись, добавление или удаление. Данный запрос передается подсистеме среды (или DLL), которая обращается к системному сервису NT. Это инициирует поиск имени диспетчером объектов. Как мы уже знаем, диспетчер объектов начинает поиск в своем пространстве имен, после чего передает управление диспетчеру ввода-вывода, который и отыскивает файловый объект.
Как и другие объекты исполнительной системы, файловые объекты защищены дескриптором защиты, содержащим список управления доступом (ACL). Когда поток открывает файл, диспетчер ввода-вывода обращается к подсистеме защиты, чтобы определить, разрешает ли ACL файла процессу доступ запрошенного типа. Если доступ разрешен, диспетчер объектов предоставляет его и связывает предоставленные права доступа с возвращаемым описателем файла. Если данный или другой поток процесса собирается выполнять дополнительные операции, не указанные в первоначальном запросе, поток должен открыть другой описатель, что вызывает новую проверку прав доступа.
Файловые объекты используются также для синхронизации. После выдачи запроса на ввод-вывод поток может ждать у описателя объекта, чтобы синхронизировать свое выполнение с окончанием передачи данных дисководом или другим устройством. Эта возможность синхронизации тесно связана с другой особенностью системы ввода-вывода — асинхронными операциями ввода-вывода.
Объекты, управляемые системой ввода-вывода, требуют особой обработки, так как диспетчер объектов знает не очень много о структурах каталогов файловых систем и еще меньше о форматах хранения данных на диске или ленте. Из-за этих и других сложностей, связанных с использованием физических устройств, одной из основных проблем при создании системы ввода-вывода была интеграция в систему объектов.
Файловые объекты являются промежуточными. Они представляют памяти совместно используемые физические ресурсы. Некоторые совместно используемые ресурсы системы ввода-вывода, такие как именованные каналы и почтовые ящики, — это расположенные в памяти, а не физические ресурсы. Они также представлены в системе ввода-вывода NT как объекты. Когда программа открывает файл или простое устройство, диспетчер ввода-вывода возвращает описатель файлового объекта NT. Диспетчер объектов рассматривает файловые объекты так же, как и прочие, пока ему не понадобится получить или сохранить некоторую информацию на устройстве. В этот момент диспетчер объектов обращается к диспетчеру ввода-вывода для доступа к устройству. На рис. 3 раскрывается содержание понятий файловых объектов и показаны сервисы, работающие с ними (а, следовательно, и с открытыми файлами или физическими устройствами, которые эти объекты представляют).
Так как файловый объект сам по себе не ресурс, а представление совместно используемого ресурса в памяти, он отличается от других объектов исполнительной системы. Файловый объект содержит только данные, связанные с описателем объекта, в то время как совместно используемые данные или текст содержатся в самом файле. Всякий раз, когда некоторый поток открывает описатель файла, создается новый файловый объект с новым набором атрибутов, специфичных для описателя. Например, атрибут "байтовое смещение" обозначает то место в файле, с которого начнется следующая операция чтения или записи (выполняемая с использованием данного описателя). С каждым описателем данного файла связано собственное байтовое смещение, хотя все они и ссылаются на один файл. Фактически атрибуты файлового объекта можно считать относящимися к описателю, как показано на рис. 4.
Рис. 3. файловый объект.
Хотя описатель файла уникален для процесса, соответствующий ему файл таковым не является. Таким образом, как и в случае любого совместно используемого ресурса, потоки должны синхронизировать свой доступ к совместно используемым файлам, каталогам или устройствам. Например, если поток намерен выполнять запись в файл, он должен задать монопольный доступ при открытии описателя файла, чтобы предотвратить запись в файл со стороны других потоков. Кроме того, он может заблокировать некоторую область файла на время записи.
Рис. 4. Совместное использование файла.
Операция ввода-вывода может выполняться по отношению к программному модулю, запросившему операцию, в синхронном или асинхронном режимах. Смысл этих режимов тот же, что и для рассмотренных выше системных вызовов, — синхронный режим означает, что программный модуль приостанавливает свою работу до тех пор, пока операция ввода-вывода не будет завершена (рис. 5), а при асинхронном режиме программный модуль продолжает выполняться в мультипрограммном режиме одновременно с операцией ввода-вывода (рис. 6). Синхронный ввод-вывод является стандартным для большинства ОС, и во многих случаях этого достаточно. Однако современные процессоры невероятно быстры — гораздо быстрее большинства устройств ввода-вывода. Пока устройство обрабатывает один запрос, процессор может выполнить тысячи строк кода. В идеале у приложения должна быть возможность использовать процессор, пока устройство пересылает данные. По этим соображениям диспетчер ввода-вывода предоставляет также и средства асинхронного ввода-вывода. Подсистема самостоятельно выбирает для себя синхронный или асинхронный ввод-вывод и, в зависимости от поведения ее API, может предоставить своим клиентским приложениям ввод-вывод обоих типов. Процедуры доступа к файлам API Win32 могут исполняться как синхронно, так и асинхронно.
Асинхронные сервисы позволяют приложению выдать запрос ввода-вывода и продолжать свою работу, пока устройство передает данные (рис.6).
Асинхронный ввод-вывод имеет важное преимущество перед синхронным — возможность повышения скорости работы приложений. Пока устройство занято пересылкой данных, приложение продолжает выполнять другую работу. Например, оно может выводить изображение на монитор, пока драйвер
устройства заполняет буфер данными из дискового файла. Чтобы использовать асинхронный ввод-вывод, поток должен указать это (в терминологии Win32 "асинхронный" ввод-вывод называется "совмещенным" — "overlapped") при открытии описателя. После начала асинхронной операции ввода-вывода поток должен позаботиться о том, чтобы не использовать никаких данных этой операции до тех пор, пока драйвер устройства не завершит ее. Другими словами, поток должен синхронизировать свое выполнение с завершением операции ввода-вывода, ожидая у описателя файла, как показано на рис.6.
Приблизительно треть базовых сервисов NT, предоставляемых подсистемам диспетчером ввода-вывода, асинхронны по умолчанию. Асинхронными сервисами являются те, которые, вероятно, будут выполняться долгое или вообще непредсказуемое время — например, чтение или запись файла или перебор содержания каталога файлов. Поток, вызывающий эти сервисы, должен синхронизировать свое выполнение с их завершением. Альтернативно, поток может заставить все сервисы NT "вести себя" синхронно, задав синхронный ввод-вывод при открытии описателя файла.
Есть различие между тем, как сервис выглядит для вызывающей его программы, и тем, как он фактически реализован системой ввода-вывода NT. Хотя некоторые сервисы ведут себя синхронно, а некоторые — асинхронно, сама система ввода-вывода работает полностью асинхронно — от обработки прерываний до передачи результатов обратно пользовательскому режиму и запуска исполнения запроса на устройстве. Асинхронный режим обеспечивает системе ввода-вывода возможность гибко переключаться на другие задачи, пока относительно медленные устройства пересылают данные.
Рис. 5. Синхронный ввод-вывод.
Рис. 6. Асинхронный ввод-вывод.
Выводы по второму вопросу
Подсистема ввода-вывода должна предоставлять своим клиентам (пользовательским процессам и кодам ядра) возможность выполнять как синхронные, так и асинхронные операции ввода-вывода, в зависимости от потребностей вызывающей стороны. Системные вызовы ввода-вывода чаще оформляются как синхронные процедуры в связи с тем, что такие операции длятся долго и пользовательскому процессу или потоку все равно придется ждать получения результатов операции для того, чтобы продолжить свою работу. Внутренние же вызовы операций ввода-вывода из модулей ядра обычно выполняются в виде асинхронных процедур, так как кодам ядра нужна свобода в выборе дальнейшего поведения после запроса операции ввода-вывода. Использование асинхронных процедур приводит к более гибким решениям, так как на основе асинхронного вызова всегда можно построить синхронный, создав дополнительную промежуточную процедуру, блокирующую выполнение вызвавшей процедуры до момента завершения ввода-вывода. Иногда и прикладному процессу требуется выполнить асинхронную операцию ввода-вывода, например при микроядерной архитектуре, когда часть кода работает в пользовательском режиме как прикладной процесс, но выполняет функции операционной системы, требующие полной свободы действий и после вызова операции ввода-вывода.