Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 3000377.doc
Скачиваний:
29
Добавлен:
30.04.2022
Размер:
2.52 Mб
Скачать

2.2. Потоковая подсистема ввода-вывода в unix

На ранних этапах развития UNIX сетевое взаимодействие осуществлялось с использованием низкоскоростных последовательных устройств, типа последовательного порта RS-232, со скоростью передачи порядка 10 Кбит/с. Для обслуживания таких устройств хорошо подходили символьные драйверы.

По мере развития сетевых устройств и протоколов сетевого взаимодействия ситуация изменялась. Уже в 80-е годы XX века скорость обмена информацией в компьютерных сетях достигла десятков мегабит в секунду (в настоящее время сетевая карта 1G Ethernet (скорость передачи 1 Гбит/с) является стандартным оснащением даже для домашних компьютеров начального уровня и ноутбуков), сетевые протоколы стали многоуровневыми, с широкими возможностями комбинации различных протоколов в одном сетевом канале. В результате символьные драйверы и концепция символьного устройства уже не подходили для сетевого взаимодействия по причине недостаточной производительности. Концепция более производительных блочных устройств также не может быть использована, поскольку блочные устройства предусматривают произвольный доступ к данным, хранимым на устройстве, в любое время и в любом порядке, а сетевые устройства не хранят информацию, они обеспечивают только последовательную передачу и прием данных по коммуникационному каналу.

Для решения проблемы Денисом Ритчи (одним из родоначальников системы UNIX) из AT&T в середине 80-х XX века была предложена альтернативная архитектура подсистемы ввода-вывода для символьных устройств, получившая название STREAMS (потоки). STREAMS реализует концепцию конвейерной обработки данных при их прохождении через многоуровневую структуру (цепочку) обработчиков. При этом исключаются лишние копирования данных при их передаче между уровнями обработки, поскольку передается только указатель на блок данных, размещенный в системной памяти.

Архитектура и принципы работы подсистемы streams

В основе работы потокового ввода-вывода лежит последовательная двунаправленная передача пакетов данных между модулями потока, так что STREAMS может эффективно работать с полнодуплексными устройствами. Для поддержки двунаправленной передачи данных каждый модуль потока включает две очереди – очередь записи и очередь чтения.

Очередь является базовым компонентом модуля. С очередью связаны функции обработки данных.

Модули потока связываются между собой, образуя конвейер обработки данных, также за счет очередей. Каждый модуль хранит указатель на очередь записи следующего модуля и на очередь чтения предыдущего модуля, поэтому модули могут явно передавать сообщения соседям в направлении передачи, используя для этого функции, предоставляемые очередями получателями через стандартные интерфейсы.

Поток всегда начинается с головного модуля и заканчивается драйвером устройства – это обязательные компоненты потока. Потоковые драйверы являются третьим типом драйвера (помимо рассмотренных ранее блочных и символьных драйверов). Интерфейс потокового драйвера совпадает с интерфейсом модулей потока и также основан на очередях.

Помимо обязательных компонентов, поток может содержать произвольное количество промежуточных модулей, которые могут динамически встраиваться в поток.

Упрощенная архитектура потоковой подсистемы ввода-вывода STREAMS показана на рис. .9.

Рис.9. Общая архитектура подсистемы STREAMS

Пользовательский процесс передает данные потоку с помощью универсального системного вызова write или с помощью специального системного вызова для работы с потоками putmsg, который предоставляет большие возможности по передаче форматированных и управляющих данных:

int putmsg (int filedes, // дескриптор файла struct strbuf *ctlbuf, // управляющие данные struct strbuf *datbuf, // передаваемые данные int flags // тип сообщения );

Если при обработке системного вызова ядро обнаруживает, что файловый дескриптор связан с потоком, то ядро формирует сообщение и помещает его в очередь записи головного модуля. Головной модуль обрабатывает сообщение и передает его в очередь записи следующего модуля, и т.д., пока сообщение не достигнет драйвера устройства.

В свою очередь, драйвер устройства, получив от физического устройства очередную порцию данных, формирует сообщение и отправляет его вверх по потоку, вплоть до головного модуля. Операционная система не может каким-либо образом привлечь внимание пользовательского процесса или изменить ход его выполнения при получении сообщения, поэтому поступившие сообщения накапливаются в очереди чтения головного модуля. Пользовательский процесс может в любой момент запросить сообщение из очереди чтения головного модуля с помощью системного вызова read или getmsg.

int getmsg (int filedes, // дескриптор файла struct strbuf *ctlbuf, // управляющие данные struct strbuf *datbuf, // передаваемые данные int *flags // тип сообщения );

Если очередь чтения головного модуля на момент запроса со стороны пользовательского процесса содержит сообщения, то данные первого сообщения будут перекопированы в адресное пространство процесса и процесс продолжит свое выполнение, в противном случае процесс будет заблокирован до появления сообщения.

Рассмотрим теперь внутреннюю архитектуру и принципы работа модулей потока.