В целом ряде случаев данные, передаваемые из процесса на устройство или в обратном направлении, должны быть дополнительно преобразованы. Такими преобразованиями могут быть: кеширование данных, сжатие данных, криптографическое кодирование данных, согласование с форматами сетевых протоколов и т.д.
Выполнение этих функций может быть заложено непосредственно в драйвер устройства. Однако, такой вариант снижает мобильность драйвера, так как не во всех применениях данной вычислительной системы и данной ОС эти функции могут быть необходимы, требования к этим функциям могут меняться, что повлечет за собой необходимость создания нового драйвера. Даже для разных процессов могут понадобиться разные способы модификации данных. Решение этой проблемы содержится в идее потоков.
Рис.6.6. Поток ввода-вывода |
Поток (stream) представляет собой цепочку очередей, через которые проходят данные, передаваемые от процесса драйверу устройства или в обратном направлении. Каждая очередь в этой цепочке обрабатывается одним программных модулем - модулем потока, как показано на Рисунке 6.6. Данные движутся по цепочке очередей от процесса к драйверу или обратно, по пути проходя обработку в модулях потока. Модуль потока выбирает данные из своей очереди, выполняет их обработку и передает данные в очередь к следующему модулю потока. Когда модуль завершает обработку очередной порцию информации, он запускает на выполнение следующий модуль, который обрабатывает эти данные или заносит их в свою очередь. Вставляя в поток новые модули (и, соответственно, новые очереди) можно обеспечивать сколь угодно сложную дополнительную обработку данных.
Потоки прозрачны для пользовательских процессов, но последним предоставляется возможность вставлять в потоки собственные модули.
Поток может быть однонаправленным или дуплексным, то есть, содержать две параллельные цепочки очередей - вводную и выводную, как и показано на рис 6.6.
Развитием идеи потоков являются многоуровневая структура драйверов, которая применяется в ряде современных ОС. Обработка данных проходит в этом случае через цепочку отдельных драйверов. Места драйверов в цепочке распределяются таким образом, чтобы каждый драйвер более низкого уровня осуществлял обработку, более привязанную к конкретному устройству. Драйверы высоких уровней могут обслуживать несколько устройств одного типа, но разных моделей. Непосредственно аппаратно-зависимым является только драйвер самого нижнего уровня (аппаратный драйвер). В некоторых ОС даже аппаратный драйвер не осуществляет прямого взаимодействия с устройством, а использует для этого сервис ОС. В многоуровневой структуре драйверов может быть оставлено место и для пользовательских драйверов, выполняющих специфическую обработку данных.