Архитектура операционной системы UNIX

       

Анализ потоков


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

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

В реализации потоков можно выделить несколько отклонений или несоответствий:

  • Учет ресурсов процесса в потоках затрудняется, поскольку модулям необязательно выполняться в контексте процесса, использующего поток. Ошибочно предполагать, что все процессы одинаково используют модули потоков, поскольку одним процессам может потребоваться использование сложных сетевых протоколов, тогда как другие могут использовать простые строковые интерфейсы.
  • Пользователи имеют возможность переводить терминальный драйвер в режим без обработки, в котором функция read возвращает управление через короткий промежуток времени в случае отсутствия данных (например, если newtty.c_cc[VMIN] = 0 на ). Эту особенность сложно реализовать в потоковой среде без подключения специальной программы на уровне заголовка потока.
  • Потоки выступают средствами линейной связи и не могут позволить производить с легкостью мультиплексирование на уровне ядра. В примере использования окон, рассмотренном в предыдущем разделе, выполнялось мультиплексирование на уровне пользовательского процесса.


Несмотря на эти несоответствия, с потоками связываются большие надежды в совершенствовании разработки модулей драйвера.
/* предположим, что дескрипторы файлов 0 и 1 уже относятся к физическому терминалу */ для(;;) /* цикл */ { выбрать(ввод); /* ждать ввода из какой-либо линии */ прочитать данные, введенные из линии; переключить(линию с вводимыми данными) { если выбран физический терминал: /* данные вводятся по ли- нии физического терми- нала */ если(считана управляющая команда) /* например, создание нового окна */ { открыть свободный псевдотерминал; пойти по ветви нового процесса: если(процесс родительский) { выдвинуть интерфейс сообщений в сторону mpx; продолжить; /* возврат в цикл "для" */ } /* процесс-потомок */ закрыть ненужные дескрипторы файлов; открыть другой псевдотерминал из пары, выбрать stdin, stdout, stderr; выдвинуть строковый интерфейс терминала; запустить shell; /* подобно виртуальному терминалу */ } /* "обычные" данные, появившиеся через виртуальный терминал */ демультиплексировать считывание данных с физического тер- минала, снять заголовки и вести запись на соответствую- щий псевдотерминал; продолжить; /* возврат в цикл "для" */

если выбран логический терминал: /* виртуальный терминал связан с окном */ закодировать заголовок, указывающий назначение информации окна; переписать заголовок и информацию на физический терминал; продолжить; /* возврат в цикл "для" */ } }
Рисунок 10.24. Псевдопрограмма мультиплексирования окон

Comments:

Copyright ©


Содержание раздела