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

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

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

3.2. Принципы программного обеспечения ввода/вывода

Перейдем теперь от рассмотрения аппаратуры ввода/вывода к знакомству с про-фаммным обеспечением ввода/вывода. Сначала мы проникнемся целями профаммного обеспечения ввода/вывода, а затем поглядим на различные способы выполнения операций ввода/вывода с точки зрения операционной системы.

3.2.1. Задачи программного обеспечения ввода/вывода

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

sort <1nput >output

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

Тесно связан с идеей независимости от устройств принцип единообразного именования. Имя файла или устройства должно быть просто текстовой строкой или целым числом и никоим образом не зависеть от физического устройства. В системе UNIX все диски могут быть произвольным образом интегрированы в иерархию файловой системы, поэтому пользователю не обязательно знать, какое имя какому устройству соответствует. Например, гибкий диск не запрещается смонтировать поверх каталога /usr/ast/backup, вследствие чего копирование файла в каталог /usr/ast/backup/monday автоматически приведет к копированию файлов на гибкий диск. Таким образом, все файлы и устройства адресуются одним и тем же способом: по пути к ним.



Другим важным аспектом программного обеспечения ввода/вывода является обработка ошибок. Ошибки должны обрабатываться как можно ближе к аппаратуре. Если контроллер обнаружил ошибку чтения, он должен попытаться по возможности исправить эту ошибку сам. Если он не в силах это сделать, тогда ошибку обязан обработать драйвер устройства, допустим, попытавшись прочитать этот блок еще раз. Многие ошибки бывают временными, как, например, ошибки чтения, вызванные пылинками на читающих головках. Такие ошибки часто не воспроизводятся при повторной попытке чтения блока. Только если нижний уровень пасует перед проблемой, о ней следует информировать верхний уровень. Во многих случаях восстановление после ошибок предпочтительно делать на нижнем уровне, прозрачно для верхних уровней, то есть так, что вышестоящие уровни даже не будут подозревать о наличии сбоев.

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

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

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



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

Эти задачи решаются путем разбиения программного обеспечения ввода/вывода на четыре уровня.

1. Обработчики прерываний (нижний уровень).

2. Драйверы устройств.

3. Независимый от аппаратуры код операционной системы.

4. Пользовательские профаммы (верхний уровень).

3.2.2. Обработчики прерываний

Хотя профаммный ввод/вывод иногда бывает полезен, для большинства операций ввода/вывода прерывания являются неприятным, но необходимым фактом. Прерывания должны быть упрятаны как можно глубже во внутренностях операционной системы, чтобы о них знала как можно меньшая ее часть. Лучший способ завуалировать их заключается в блокировке драйвера, начавшего операцию ввода/вывода, вплоть до окончания этой операции и получения прерывания. Драйвер может заблокировать себя сам, выполнив на семафоре процедуру down, процедуру wait на переменной состояния, процедуру receive на сообщении или что-либо подобное.

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

3.2.3. Драйверы устройств

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

Ранее в этой главе мы познакомились с функциями контроллеров устройств ввода/вывода. Как было сказано, у каждого контроллера есть набор регистров, используемых для того, чтобы давать опекаемому устройству команды и читать состояние устройства. Число таких регистров и выдаваемые команды зависят от конкретного устройства. Например, драйвер диска должен знать о секторах, до-



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 - 2018 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.