Управление системой ввода-вывода
Ввод/вывод является, пожалуй, самым значимым аспектом при создании операционных систем. Вследствие широкого разнообразия запоминающих устройств и приложений разработать общее согласованное решение, касающееся их организации, очень сложно.
Внешние устройства, сопровождающие операции ввода-вывода, могут быть объединены в три группы:
Работающие с пользователем. Используются для связи с пользователем компьютера. В качестве примера можно привести принтеры и видеотерминалы, состоящие из дисплея, клавиатуры, а также другие устройства — например, манипулятор "мышь".
Работающие с компьютером. Используются для связи с электронным оборудованием. К ним можно отнести дисковые устройства и устройства с магнитной лентой, датчики, контроллеры и преобразователи.
Коммуникации. Используются для связи с удаленными устройствами. К ним относятся модемы и драйверы цифровых линий.
Имеются существенные различия как между устройствами ввода-вывода, принадлежащими к разным классам, так и в рамках каждого класса. Отметим следующие из этих различий:
Скорость передачи данных. Скорость передачи данных может отличаться на несколько порядков;
Применение. Каждое действие, поддерживаемое устройством, оказывает влияние на программное обеспечение и стратегии операционной системы. Так, например, использующийся для хранения файлов диск требует наличия специального программного обеспечения для управления файлами. Диск, используемый в качестве внешнего запоминающего устройства для страниц виртуальной памяти, зависит от программных и аппаратных средств виртуальной памяти. Кроме того, данные приложения оказывают воздействие и на алгоритмы дискового планирования. В качестве еще одного примера можно привести терминал, который может использоваться как обычным пользователем, так и системным администратором — при этом требуются не только различные уровни привилегий, но и, вероятно, различные уровни приоритетов операционной системы.
Сложность управления. Для принтера требуется относительно простой интерфейс управления, диску же необходим намного более сложный интерфейс. Влияние этих отличий на операционную систему сглаживается усложнением контроллеров ввода-вывода.
Единицы передачи данных. Данные могут передаваться как поток байтов или символов (например, при терминальном вводе-выводе), и блоками (например, при выполнении дисковых операций ввода-вывода).
Представление данных. Различные устройства используют разные схемы кодирования данных, включая разную кодировку символов и контроль четности.
Условия ошибок. Природа ошибок, способ сообщения о них, их последствия и возможные ответы резко отличаются при переходе от одного устройства к другому.
Поэтому, подсистема ввода-вывода мультипрограммной ОС при обмене данными с внешними устройствами компьютера должна решать ряд общих задач, из которых наиболее важными являются следующие:
- организация параллельной работы устройств ввода-вывода и процессора;
- согласование скоростей обмена и кэширование данных;
- разделение устройств и данных между процессами;
- обеспечение удобного логического интерфейса между устройствами и остальной частью системы;
- поддержка широкого спектра драйверов с возможностью простого включения в систему нового драйвера;
- динамическая загрузка и выгрузка драйверов;
- поддержка нескольких файловых систем;
- поддержка синхронных и асинхронных операций ввода-вывода.
Каждое устройство ввода-вывода вычислительной системы — диск, принтер, терминал и т.п. — снабжено специализированным блоком управления, называемым контроллером. Контроллер взаимодействует с драйвером — системным программным модулем, предназначенным для управления данным устройством. Контроллер периодически принимает от драйвера выводимую на устройство информацию, а также команды управления, которые говорят о том, что с этой информацией нужно сделать (например, вывести в виде текста в определенную область терминала или записать в определенный сектор диска). Под управлением контроллера устройство может некоторое время выполнять свои операции автономно, не требуя внимания со стороны центрального процессора. Это время зависит от многих факторов — объема выводимой информации, степени интеллектуальности управляющего устройством контроллера, быстродействия устройства и т.п. Даже самый примитивный контроллер, выполняющий простые функции, обычно тратит довольно много времени на самостоятельную реализацию подобной функции после получения очередной команды от процессора. Это же справедливо и для сложных контроллеров, так как скорость работы любого устройства ввода-вывода, даже самого скоростного, обычно существенно ниже скорости работы процессора.
Процессы, происходящие в контроллерах, протекают в периоды между выдачами команд независимо от ОС. От подсистемы ввода-вывода требуется спланировать в реальном масштабе времени (в котором работают внешние устройства) запуск и приостановку большого количества разнообразных драйверов, обеспечив приемлемое время реакции каждого драйвера на независимые события контроллера. С другой стороны, необходимо минимизировать загрузку процессора задачами ввода-вывода, оставив как можно больше процессорного времени на выполнение пользовательских потоков.
Данная задача является классической задачей планирования систем реального времени и обычно решается на основе многоуровневой приоритетной схемы обслуживания по прерываниям. Для обеспечения приемлемого уровня реакции все драйверы (или части драйверов) распределяются по нескольким приоритетным уровням в соответствии с требованиями ко времени реакции и временем использования процессора. Для реализации приоритетной схемы обычно задействуется общий диспетчер прерываний ОС.
При обмене данными всегда возникает задача согласование скорости. Например, если один пользовательский процесс вырабатывает некоторые данные и передает их другому пользовательскому процессу через оперативную память, то в общем случае скорости генерации данных и их чтения не совпадают. Согласование скорости обычно достигается за счет буферизации данных в оперативной памяти и синхронизации доступа процессов к буферу.
В подсистеме ввода-вывода для согласования скоростей обмена также широко используется буферизация данных в оперативной памяти. В тех специализированных операционных системах, в которых обеспечение высокой скорости ввода-вывода является первоочередной задачей (управление в реальном времени, услуги сетевой файловой службы и т. п.), большая часть оперативной памяти отводится не под коды прикладных программ, а под буферизацию данных. Однако, буферизация только на основе оперативной памяти в подсистеме ввода-вывода оказывается недостаточной — разница между скоростью обмена с оперативной памятью, куда процессы помещают данные для обработки, и скоростью работы внешнего устройства часто становится слишком значительной, чтобы в качестве временного буфера можно было бы использовать оперативную память — ее объема может просто не хватить. Для таких случаев необходимо предусмотреть особые меры, и часто в качестве буфера используется дисковый файл, называемый также спул-файлом (от spool — шпулька, тоже буфер, только для ниток). Типичный пример применения спулинга дает организация вывода данных на принтер. Для печатаемых документов объем в несколько десятков мегабайт — не редкость, поэтому для их временного хранения (а печать каждого документа занимает от нескольких минут до десятков минут) объема оперативной памяти явно недостаточно. Другим решением этой проблемы является использование большой буферной памяти в контроллерах внешних устройств. Такой подход особенно полезен в тех случаях, когда помещение данных на диск слишком замедляет обмен (или когда данные выводятся на сам диск). Например, в контроллерах графических дисплеев применяется буферная память, соизмеримая по объему с оперативной, и это существенно ускоряет вывод графики на экран.
Устройства ввода-вывода могут предоставляться процессам как в монопольное, так и в совместное (разделяемое) использование. При этом ОС должна обеспечивать контроль доступа теми же способами, что и при доступе процессов к другим ресурсам вычислительной системы — путем проверки прав пользователя или группы пользователей, от имени которых действует процесс, на выполнение той или иной операции над устройством. Например, определенной группе пользователей последовательный порт разрешено захватывать в монопольное владение, а другим пользователям это запрещено.
Операционная система может контролировать доступ не только к устройству в целом, но и к отдельным порциям данных, хранимых или отображаемых этим устройством. Диск является типичным примером устройства, для которого важно контролировать доступ не к устройству в целом, а к отдельным каталогам и файлам. При выводе информации на графический дисплей отдельные окна экрана также представляют собой ресурсы, к которым необходимо обеспечить тот или иной вид доступа для протекающих в системе процессов. При этом для каждой порции данных или части устройства могут быть заданы свои права доступа, не связанные прямо с правами доступа к устройству в целом. Так, в файловой системе обычно для каждого каталога и файла можно задать индивидуальные права доступа. Очевидно, что для организации совместного доступа к частям устройства или частям данных, хранящихся на нем, непременным условием является задание режима совместного использования устройства в целом.
Одно и то же устройство, в разные периоды времени, может использоваться как в разделяемом, так и в монопольном режимах. Тем не менее, существуют устройства, для которых обычно характерен один из этих режимов, например последовательные порты и алфавитно-цифровые терминалы чаще используются в монопольном режиме, а диски — в режиме совместного доступа. Операционная система должна предоставлять эти устройства в обоих режимах, осуществляя отслеживание процедур захвата и освобождения монопольно используемых устройств, а в случае совместного использования оптимизируя последовательность операций ввода-вывода для различных процессов в целях повышения общей производительности, если это возможно. Например, при обмене данными нескольких процессов с диском можно так упорядочить последовательность операций, что непроизводительные затраты времени на перемещение головок существенно уменьшаются (при этом для отдельных процессов возможно некоторое замедление операции ввода-вывода).
При разделении устройства между процессами может возникнуть необходимость в разграничении порции данных двух процессов друг от друга. Обычно такая потребность возникает при совместном использовании так называемых последовательных устройств, данные в которых в отличие от устройств прямого доступа не адресуются. Типичным представителем такого рода устройства является принтер, который не выделяется в монопольное владение процессам, и в то же время каждый документ должен быть напечатан в виде последовательного набора страниц. Для подобных устройств организуется очередь заданий на вывод, при этом каждое задание представляет собой порцию данных, которую нельзя разрывать, например документ для печати. Для хранения очереди заданий используется спуд-файл, который одновременно согласует скорости работы принтера и оперативной памяти и позволяет организовать разбиение данных на логические порции. Так как спул-файл находится на разделяемом устройстве прямого доступа, то процессы могут одновременно выполнять вывод на принтер, помещая данные в свой раздел спул-файла.