Главная страница  Межпроцессное взаимодействие (состязание) 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 [ 65 ] 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

системный вызов, операционная система некоторым волшебным образом переключается из пользовательской части в ядерную . Такой механизм является пережитком MULTICS, где переключение было простым вызовом процедуры, а не ловушкой с сохранением состояния пользовательской части процесса, как в UNIX.

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

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

В этой главе обсуждаются драйверы RAM-диска, жесткого диска, таймера и терминала. Стандартная комплектация MINIX включает в себя также драйверы для флоппи-дисковода и принтера, которые мы подробно не рассматриваем. Кроме того, имеются драйверы для последовательного интерфейса RS-232, интерфейса SCSI, приводов CD-ROM, адаптера Ethernet и звуковой карты. Они могут быть задействованы при перекомпиляции MINIX.

Все эти задачи взаимодействуют с другими частями MINIX одинаковым образом: путем отправки сообщений. Сообщения с запросами содержат различные поля, в которые помещаются код операции (например, чтение или запись) и ее параметры. Получив сообщение, задача пытается выполнить запрос и отправляет ответное сообщение.

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

Назначение задач - воспринимать и выполнять запросы от других процессов (в норме - от файловой системы) и выполнять их. Для блочных устройств все задачи написаны так, чтобы получить запрос, выполнить его и послать ответ. Такая структура означает простой, линейный алгоритм задач. Когда происходит аппаратное прерывание, задача вызывает операцию receive, чтобы указать, что



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

Таблица 3.4. Поля запросов от файловой системы к драйверам блочных устройств и ответов, отправляемых файловой системе

Поле

Значение

Запрос

m.m type

Запрошенное действие

m.DEVICE

Младший номер устройства

m.PROC ADR

Процесс, запрашивающий ввод/вывод

m.COUNT

Количество байт или код ioctl

m.POSITION

long

Позиция устройства

m .ADDRESS

char*

Адрес в пределах процесса, сделавшего запрос

Ответ

m.m type

Всегда имеет значение TASK REPLY

m.REP PROC NR

То же, что и PROC NR в запросе

m.REP STATUS

Количество переданных байтов или код ошибки

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

За выполнение различных действий, поддерживаемых драйвером, ответственны подпрограммы с именами dev xxx. Код завершения помещается в поле REP STATUS ответа, он равен количеству переданных байтов (ноль или положительное число), если операция закончилась успехом, или номер ошибки (отрицательное число) в противном случае. Количество переданных байтов может отличаться от запрошенного, например, когда достигнут конец файла. В случае терминалов за один запрос возвращается не больше одной строки, даже если запрошено большее количество информации.

Листинг 3.1. Общая структура программы задач ввода/вывода

message mess: /* Буфер сообщений */

void io task() {

initializeO: /* Вызывается только один раз */



while (TRUE) {

receive(ANY. &mess): /* Ожидаем запрос */

caller = mess.source: /* Процесс, сделавший запрос */

switch(mess.type) { case READ:

rcode = dev read(&mess): break: case WRITE:

rcode = dev write(&mess): break; /* Тут находится код для выполнения других действий,

таких как OPEN, CLOSE и IOCTL */ default:

rcode = ERROR:

mess,type = TASK REPLY:

mess.status = rcode: /* Код возврата */

sendCcaller. &mess): /* Отправляем ответ */

3.4.3. Аппаратно-независимый код ввода/вывода в MINIX

Весь аппаратно-независимый код ввода/вывода в MINIX является частью файловой системы. Система ввода/вывода так тесно связана с файловой системой, что они обе объединены в один процесс. Функции файловой системы перечислены в табл. 3.2, за исключением функций захвата и освобождения отдельных устройств, которых в существующей конфигурации MINIX нет. Тем не менее, если такая потребность возникнет, эти функции могут быть легко добавлены в код соответствующих драйверов.

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

3.4.4. Программы ввода/вывода пользовательского уровня в MINIX

Здесь также применяется обобщенная модель, описанная ранее в этой главе. Для выполнения системных вызовов и стандартных функций С, требуемых стандартом POSIX (например, функций форматного ввода/вывода printf и scanf), предоставляются библиотечные процедуры. В стандартной конфигурации MINIX имеется также демон Ipd, который занимается поддержкой очереди печати документов, отправленных на печать командой 1р. В стандартной комплектации MINIX имеется еще ряд демонов, ответственных за различные сетевые функции. Работа этих демонов требует поддержки сетевых функций в ядре, но они могут быть легко задействованы при перекомпиляции. Для этого необходимо включить в систему сетевой сервер, работающий с тем же уровнем привилегий, что и менед-



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 [ 65 ] 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.