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

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

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

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

Добавлен: 29.10.2018

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

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

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

5.5. Часы   

441

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

Сегодня задержка прерывания чуть ниже, чем на компьютерах 70-х годов прошлого 
столетия. К примеру, на большинстве мини-компьютеров прерывание занимало четы-
ре такта шины: для помещения в стек счетчика команд и слова состояния программы 
(PSW) и для загрузки новых счетчика команд и PSW. В наше время при работе с кон-
вейерами, блоками управления памятью, буферами TLB и кэшем издержки неизме-
римо выше. И со временем положение скорее ухудшится, чем улучшится, сводя на нет 
увеличение тактовой частоты. К сожалению, для конкретных приложений не хотелось 
бы ни издержек, связанных с прерываниями, ни задержек, связанных с опросами.

Программные таймеры

 позволяют избежать прерываний. Вместо них, как только 

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

Программные таймеры устанавливаются или сбрасываются с частотой передачи 
управления ядру, осуществляемого по каким-то другим причинам. В число этих при-
чин входят:

 

 системные вызовы;

 

 отсутствие адресов в буфере TLB;

 

 ошибки отсутствия страниц;

 

 прерывания ввода-вывода;

 

 отсутствие загруженности центрального процессора.
Чтобы определить, как часто происходят эти события, Арон и Дрюшель провели изме-
рения при нескольких вариантах загрузки центральных процессоров, включая полно-
стью загруженный веб-сервер, веб-сервер, имеющий фоновые задачи, ограниченные 
по скорости вычислений, воспроизведение аудиопотока, получаемого из Интернета 
в реальном масштабе времени, а также перекомпиляцию ядра UNIX. Средняя частота 
вхождений в ядро изменялась от 2 до 18 мкс, при этом причиной около половины 
этих вхождений были системные вызовы. Таким образом, в первом приближении за-
дача задействования программного таймера каждые 10 мкс была вполне выполнимой, 
хотя и со случающимися время от времени нарушениями крайних сроков. Нечастые 
опоздания на 10 мкс намного предпочтительнее, чем использование прерываний, 
« съедающих» 35 % времени центрального процессора.

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


background image

442  

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

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

5.6. Пользовательский интерфейс: 
клавиатура, мышь, монитор

В качестве средства взаимодействия человека с компьютером используются клавиатура 
и монитор (а временами и мышь). Хотя клавиатура и монитор с технической точки 
зрения являются отдельными устройствами, они работают в тесном взаимодействии. 
На больших универсальных компьютерах зачастую работает множество удаленных 
пользователей, у каждого из которых в качестве отдельного модуля имеется устройство, 
состоящее из клавиатуры и подключенного дисплея. Исторически такие устройства 
называются терминалами. Люди часто используют этот термин, даже если речь идет 
о клавиатурах и мониторах персональных компьютеров (главным образом из-за от-
сутствия более подходящего термина).

5.6.1. Программное обеспечение ввода информации

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

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

Программное обеспечение клавиатуры

Число, фигурирующее в порте ввода-вывода, является номером клавиши, который 
называется скан-кодом (не следует его путать с кодом ASCII). У обычных клавиатур 
имеется не более 128 клавиш, поэтому для представления номера клавиши хватает 
семи битов. Восьмой бит устанавливается в 0, когда клавишу нажимают, и в 1, когда 
ее отпускают. Состояние каждой клавиши (нижнее или верхнее ее положение) дол-
жен отслеживать драйвер клавиатуры. Следовательно, роль оборудования сводится 


background image

5.6. Пользовательский интерфейс: клавиатура, мышь, монитор   

443

к предоставлению прерывания нажатия и освобождения. Все остальное выполняется 
программными средствами.

К примеру, когда нажата клавиша A, ее скан-код (30) помещается в регистр ввода-вы-
вода. Драйвер должен определить, в режиме какого регистра, верхнего или нижнего, 
работает клавиатура, в каком именно сочетании нажата эта клавиша, 

CTRL+A

ALT+A

CTRL+ALT+A

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

клавиша была нажата, но еще не отпущена (например, 

SHIFT

), у него вполне достаточно 

информации для успешной работы. К примеру, такая последовательность работы на 
клавиатуре: нажать 

SHIFT

, нажать 

A

, отпустить 

A

, отпустить 

SHIFT

 — будет означать 

A

 

в верхнем регистре. Но такая последовательность: нажать 

SHIFT

, нажать 

A

, отпустить 

SHIFT

, отпустить 

A

 — также будет означать 

A

 в верхнем регистре. Хотя при таком 

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

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

1

.)

Этот подход хорошо сочетается с потребностями таких сложных экранных редакто-
ров, как emacs, которые позволяют пользователю привязывать произвольное действие 
к любым символу или последовательности символов. Но это означает, что если поль-
зователь наберет dste вместо date, а затем исправит ошибку, нажав три раза на клавишу 
удаления (backspace) и набрав ate, и завершит все это вводом символа возврата каретки, 
пользовательская программа получит все 11 введенных ASCII-кодов:

dste←←←ate CR

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

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

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

1

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

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


background image

444  

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

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

Хотя логически клавиатура и монитор являются отдельными устройствами, многие 
пользователи привыкли к тому, чтобы набираемые ими символы появлялись на экране. 
Этот процесс называется отображением (echoing)

1

.

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

Отображение ввода усложняется и тем, что при вводе более 80 символов их надо ото-
бражать в 80-символьных строках (или в строках другой длины). В зависимости от 
приложения в данном случае можно применить перенос на следующую строку. Не-
которые драйверы просто урезают строку до 80 символов, отбрасывая все символы 
после 80-й позиции.

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

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

ENTER

 конвертируется для внутреннего запоминания в код 

перевода строки, а в Windows он конвертируется в код возврата каретки, за которым 
следует код перевода строки.

Если стандартным является хранение кода перевода строки (как в соглашении UNIX), 
то коды возврата каретки (генерируемые при нажатии клавиши 

ENTER

) должны быть 

превращены в коды перевода строки. Если внутренний формат предусматривает хра-

1

 Также встречается под названиями «эхопечать» или «печать эха». — Примеч. ред.


background image

5.6. Пользовательский интерфейс: клавиатура, мышь, монитор   

445

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

При работе в каноническом режиме некоторые вводимые символы имеют специальное 
предназначение. В табл. 5.4 показаны все специальные символы, необходимые системе 
POSIX. Подразумевается, что все они являются символами управления, не конфлик-
тующими с текстовым вводом или кодами, используемыми программами; все, кроме 
последних двух, могут быть изменены программным способом.

Таблица 5.4. Символы, обрабатываемые особым образом в каноническом режиме

Символ

Имя в POSIX

Комментарий

CTRL+H

ERASE

Забивание одного символа

CTRL+U

KILL

Стирание всей набранной строки

CTRL+V

LNEXT

Буквальное интерпретирование следующего символа

CTRL+S

STOP

Остановка вывода

CTRL+Q

START

Запуск вывода

DEL

INTR

Прерывание процесса (SIGINT)

CTRL+\

QUIT

Принуждение к выводу дампа ядра (SIGQUIT)

CTRL+D

EOF

Вставка кода конца файла

CTRL+M

CR

Вставка кода возврата каретки (неизменяемый)

CTRL+J

NL

Вставка кода перевода строки (неизменяемый)

Символ ERASE позволяет пользователю стереть только что введенный символ. Обыч-
но для этого применяется клавиша удаления 

Backspace

 (

CTRL+H

). Он не добавляется 

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