Файл: Debian Таненбаум Бос.pdf

ВУЗ: Не указан

Категория: Книга

Дисциплина: Операционные системы

Добавлен: 29.10.2018

Просмотров: 48139

Скачиваний: 190

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

396  

 Глава 5. Ввод и вывод информации 

backup

, чтобы при копировании файла в каталог 

/usr/ast/backup/monday

 происходи-

ло его копирование в каталог 

monday

 на этом флеш-накопителе. Таким образом, все 

файлы и устройства адресуются одинаково: по полному имени, включающему путь 
в файловой системе.

Другим важным аспектом программного обеспечения ввода-вывода является обработ-
ка ошибок

. В общем-то обработка ошибок должна осуществляться как можно ближе 

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

Еще один важный вопрос — какой способ применить для передачи данных, синхрон-
ный

 (блокирующий) или асинхронный (управляемый с помощью прерываний). 

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

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

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


background image

5.2. Принципы создания программного обеспечения ввода-вывода   

397

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

5.2.2. Программный ввод-вывод

Есть три фундаментально различных способа осуществления операций ввода-вывода. 
В этом разделе мы рассмотрим первый из этих способов — программный ввод-вывод. 
В следующих двух разделах будут рассмотрены другие способы (ввод-вывод, управ-
ляемый с помощью прерываний, и ввод-вывод, использующий DMA). Проще всего 
организовать ввод-вывод, возложив всю работу на центральный процессор. Этот способ 
называется программным вводом-выводом.

Чтобы проиллюстрировать работу программного ввода-вывода, лучше всего обратиться 
к примеру. Рассмотрим пользовательский процесс, которому нужно распечатать на 
принтере с последовательным интерфейсом строку, состоящую из восьми символов: 
«ABCDEFGH». Иногда так же работают дисплеи на небольших встроенных системах. 
Как показано на рис. 5.6, а, сначала процесс собирает строку в буфере, который нахо-
дится в пространстве пользователя.

Рис. 5.6. Этапы распечатки строки

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

Обычно операционная система копирует буфер со строкой в массив, скажем, p, в про-
странстве ядра, где ей будет проще получить доступ к нему (поскольку ядру, чтобы 
получить доступ к пространству пользователя, может потребоваться изменить карту 
памяти). Затем она проверяет принтер на доступность. Если принтер недоступен, она 


background image

398  

 Глава 5. Ввод и вывод информации 

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

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

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

Действия, выполняемые операционной системой, сведены в листинг 5.1. Сначала дан-
ные копируются в ядро. Затем операционная система входит в цикл, выводя на печать 
по одному символу. Основное проявление программного ввода-вывода, ярко проиллю-
стрированное в этом листинге, состоит в том, что после вывода символа центральный 
процессор постоянно опрашивает устройство на готовность приема следующего сим-
вола. Такое поведение часто называют опросом или активным ожиданием.

Листинг 5.1. Запись строки в принтер с использованием программного ввода-
вывода

copy_from_user(buffer, p, count);            /* p — буфер ядра */
for (i = 0; i < count; i++) {                /* цикл для каждого символа */
    while (*printer_status_reg != READY);    /* цикл до готовности */
    *printer_data_register = p[i];           /* вывод одного символа */
}
return_to_user();

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

5.2.3. Ввод-вывод, управляемый прерываниями

Теперь рассмотрим случай распечатки на принтере без буферизации символов, пе-
чатающем символы по мере их поступления. Если принтер может печатать, скажем, 
100 символов в секунду, то на печать каждого символа уходит 10 мс. Значит, после 
записи каждого символа в регистр данных принтера центральный процессор будет 


background image

5.2. Принципы создания программного обеспечения ввода-вывода   

399

находиться в пустом цикле 10 мс, ожидая разрешения на вывод следующего символа. 
Этого времени более чем достаточно для переключения контекста и запуска какого-
нибудь другого процесса, в противном случае эти 10 мс будут потрачены впустую.

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

Рис. 5.7. Запись строки на принтер с использованием ввода-вывода, управляемого с помощью 

прерываний: а — код, выполняемый во время совершения системного вызова на распечатку; 

б — процедура обслуживания прерывания принтера

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

5.2.4. Ввод-вывод с использованием DMA

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

Большим преимуществом DMA является сокращение количества прерываний с одного 
на каждый символ до одного на каждый распечатываемый буфер. При большом коли-
честве символов и медленной обработке прерываний это может стать существенным


background image

400  

 Глава 5. Ввод и вывод информации 

Рис. 5.8. Распечатка строки с использованием DMA: а — код, выполняемый во время соверше-

ния системного вызова на распечатку; б — процедура обслуживания прерывания принтера

улучшением. В  то же время контроллер DMA обычно работает намного медленнее, чем 
центральный процессор. Если DMA-контроллер не способен управлять устройством на 
полной скорости или центральному процессору нечего делать в ожидании прерывания 
от DMA, то, может быть, больше подойдет ввод-вывод, управляемый с помощью пре-
рываний, или даже программный ввод-вывод. Но в большинстве случаев DMA себя 
вполне оправдывает.

5.3. Уровни программного обеспечения 
ввода-вывода

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

Рис. 5.9. Уровни программного обеспечения ввода-вывода

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

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