Операционные системы. Учебное пособие
.pdf
3.2.Алгоритмы планирования
илучше применять в системах реального времени с небольшим количеством потоков.
Алгоритмы планирования, основанные на приоритетах
Другой важной концепцией, лежащей в основе многих вытесняющих алгоритмов планирования, является приоритетное обслуживание. Оно предполагает наличие у потоков некоторой изначально известной характеристики–приоритета,наоснованиикоторойопределяетсяпоря- док их выполнения. Приоритет – это число, характеризующее степень привилегированности потока при использовании ресурсов ВС, в том числе времени процессора: чем выше приоритет, тем выше привилегии, тем меньше времени будет проводить поток в очередях.
Приоритет может выражаться числом. В некоторых ОС принято, что приоритет потока тем выше, чем больше число, обозначающее приоритет. В других системах чем меньше число, тем выше приоритет.
Вбольшинстве ОС, поддерживающих потоки, их приоритет непосредственно связан с приоритетом процесса, в рамках которого выполняется данный поток. Значение приоритета из описателя процесса используется при назначении приоритета потокам этого процесса.
Во многих ОС предусматривается возможность изменения приоритетов в течение жизни потока. Изменения приоритета могут происходить по инициативе самого потока, когда он обращается с соответствующим вызовом к ОС, или по инициативе пользователя, когда он выполняет соответствующую команду. Кроме того, ОС сама может изменять приоритеты потоков в зависимости от ситуации, складывающейся в системе. В последнем случае приоритеты называются динамическими, в отличие от неизменяемых, фиксированных приоритетов.
Как правило, лишь администраторы имеют право повышать приоритет своим потокам, и то в определенных пределах. В большинстве случаев ОС присваивает приоритеты потокам по умолчанию.
Существуют две разновидности приоритетного планирования:
обслуживание с относительными приоритетами и обслуживание с абсолютными приоритетами.
Вобоих случаях выбор потока для активизации из очереди готовых осуществляется одинаково: выбирается поток с наивысшим приоритетом, однако проблема определения момента смены активного потока решается по-разному. В системах с относительными приоритетами
41
3. Управление процессами и потоками |
||
|
|
|
|
|
Поток завершен |
|
|
или ошибка |
Выбор по |
Активный |
Ожидание завершения |
приоритету |
|
|
|
ввода-вывода |
|
|
|
|
Готов |
Ввод-вывод |
Блокирован |
|
|
|
Создание потока |
завершен |
|
|
|
|
Рис. 3.2. Планирование с относительными приоритетами |
||
|
|
Поток завершен |
|
|
или ошибка |
Выбор |
Активный |
|
|
Ожидание завершения |
|
приоритету |
Появился |
-вывода |
|
с более |
|
Готов |
приоритетом |
Блокирован |
|
||
|
Ввод-вывод |
Создание потока |
завершен |
|
Рис. 3.3. Планирование с абсолютными приоритетами
поток активен до тех пор, пока он сам не покинет ЦП, перейдя в блокированное состояние (рис. 3.2). В таких системах затраты на переключение ЦП с одной работы на другую минимизируются, но может возникнуть бесконечное откладывание задания. Следовательно, для систем реального времени такое обслуживание не подходит.
В системах с абсолютными приоритетами выполнение активного потока прерывается, кроме указанных выше причин, еще и при условии, что в очереди готовых потоков появился поток, приоритет которого выше приоритета активного потока (рис. 3.3). В этом случае прерванный поток переходит в состояние готовности. Здесь время ожидания потока в очередях сведено к минимуму, если ему назначить самый высокий приоритет. Такой поток будет вытеснять все остальные, за исключением потоков, имеющих такой же наивысший приоритет. Подобное планирование хорошо подходит для систем реального времени.
42
3.2. Алгоритмы планирования
Смешанные алгоритмы планирования
Во многих ОС алгоритмы планирования построены с использованием как концепции квантования, так и приоритетов. Например, в основе планирования лежит квантование, но величина кванта и/или порядок выбора потока из очереди готовых определяется приоритетами потоков. Так реализовано планирование в Windows, в которой квантование сочетается с динамическими приоритетами. Для активизации выбирается готовый поток с наивысшим приоритетом. Ему выделяется квант времени. Если во время выполнения в очереди готовых появляется поток
сболее высоким приоритетом, то он вытесняет активный поток. Вытесненный поток возвращается в очередь готовых, причем он становится впереди всех остальных потоков, имеющих такой же приоритет.
Принцип «многоуровневой очереди»
Эта стратегия разработана для ситуации, когда потоки могут быть классифицированы на несколько групп, как, например, в ОС OS/2. Планирование здесь основано на использовании квантования и абсолютных динамических приоритетов. На множестве потоков определены приоритетные классы – критический (time critical), серверный (server), стандартный (regular) и остаточный (idle). Потоки критического класса имеют наивысший приоритет.
Стратегия многоуровневой очереди разделяет очередь готовых потоков на несколько очередей, в каждой из которых находятся потоки
содинаковыми свойствами, и каждый из которых может планироваться индивидуальной стратегией.
Взаимодействие очередей осуществляется по следующим правилам: ни один поток из более низкого приоритетного класса не может быть запущен, пока не выполнятся потоки во всех очередях с более высоким приоритетом. Внутри каждого класса потоки выбираются также по приоритетам. Потоки, имеющие одинаковое значение приоритета, обслуживаются по принципу «вертушки».
Работа потока из очереди с более низким приоритетом может быть приостановлена, если появился поток в одной из очередей с более высоким приоритетом.
Принцип «многоуровневой очереди с обратными связями»
Обычная многоуровневая очередь не допускает перемещения потоков между очередями. Многоуровневая очередь с обратными связями
43
3. Управление процессами и потоками
предполагает, что потоки при определенных условиях могут перемещаться между очередями.
Эта стратегия сочетает многие свойства большинства перечисленных выше стратегий и является наиболее универсальной.
3.3. Аппаратно-программная система прерывания
Ни одна мультипрограммная ОС не будет эффективно работать без хорошо организованной аппаратно-программной системы прерывания. Действительно, периодические прерывания от таймера вызывают смену процессов в мультипрограммной ОС; прерывания от устройств ввода-вывода управляют потоками данных, которыми вычислительная система обменивается с внешним миром; ошибки при выполнении программ позволяют принять действия по их устранению или приводят к аварийному завершению программ и т. д.
Следует отметить, что прерывание – это событие, при котором меняется нормальная последовательность команд, выполняемых процессором. Оно возникает либо в зависимости от внешних по отношению к процессу выполнения программы событий, либо при появлении непредвиденных аварийных ситуаций в процессе выполнения данной программы. Механизм прерываний очень похож на механизм процедур, и это сходство состоит в том, что в обоих случаях выполняется некоторая подпрограмма, обрабатывающая специальную ситуацию, а затем продолжается выполнение основной ветви программы.
В зависимости от источника прерывания делятся на три больших класса:
1)внешние;
2)внутренние;
3)программные.
Внешние ( аппаратные) прерывания могут возникать вследствие подачинекоторойаппаратурой(например,контроллерамиустройств)сигнала, который передается на специальный вход прерывания процессора. Данный класс является асинхронным по отношению к потоку инструкций прерываемой программы. Аппаратура процессора работает так, что асинхронные прерывания возникают между выполнением двух соседних
44
3.3. Аппаратно-программная система прерывания
инструкций, при этом система после обработки прерывания продолжает выполнение процесса, уже начиная со следующей инструкции.
Внутренние прерывания, называемые также исключениями, происходят синхронно выполнению программы при появлении аварийной ситуации в ходе исполнения некоторой инструкции. Примеры исключений: ошибка защиты памяти, деление на 0, обращение к несуществующему адресу и т. п.
Программные прерывания не являются непредсказуемыми. Они запланированы программистом и возникают при выполнении особой команды процессора, которая имитирует прерывание, т. е. переход на новую последовательность инструкций. Одной из причин появления таких прерываний является то, что их использование приводит к более компактному коду программ в отличие от стандартной команды вызова процедур. Еще одна причина – возможность смены пользовательского режима на привилегированный одновременно с вызовом процедуры – это свойство поддерживается большинством процессоров. Программные прерывания часто используются для системных вызовов.
Прерываниям приписывается приоритет, с помощью которого они ранжируются по степени важности и срочности. О прерываниях, имеющих одинаковое значение приоритета, говорят, что они относятся к одному уровню приоритета. В первую очередь обслуживаются прерывания с самым высоким приоритетом.
ОС имеют специальные модули для работы с прерываниями, кото-
рые называют обработчиками прерываний, или процедурами обработки прерываний. Аппаратные прерывания обрабатываются драйверами соот- ветствующихвнешнихустройств,исключения–специальнымимодулями ядра, а программные прерывания – процедурами ОС, обслуживающими системные вызовы. Кроме этих модулей в ОС находитсядиспетчер прерываний, координирующий работу отдельных обработчиков прерываний.
Аппаратная поддержка прерываний имеет свои особенности, зависящие от типа процессора и других аппаратных компонентов (контроллер внешнего устройства, шина подключения внешних устройств, контроллеры прерываний и др.).
Существуют два основных способа, с помощью которых шины выполняютпрерывания:векторный и опрашиваемый.Вобоихспособах процессору предоставляется информация об уровне приоритета преры-
45
3. Управление процессами и потоками
вания на шине подключения внешних устройств. В случае векторных прерываний процессору передается также информация о начальном адресе обработчика возникшего прерывания.
Устройствам, которые используют векторные прерывания, назначается вектор прерываний. Он представляет собой сигнал, выставляемый на соответствующие шины процессора и несущий в себе информацию об определенном закрепленном за данным устройством номере, который идентифицирует соответствующий обработчик. ОС должна предусматривать процедуру регистрации вектора для устройства, которая связывает некоторый обработчик с определенным вектором. Примером шины, поддерживающей векторные прерывания, является шина
VMEbus.
При использовании опрашиваемых прерываний процессор получает от запросившего прерывание устройства только информацию об уровне приоритета прерывания (например, номере IRQ на шине ISA). С каждым уровнем может быть связано несколько устройств и соответственно несколько обработчиков. При возникновении прерывания процессор должен определить, какое устройство, связанное с данным уровнем, запросило прерывание. Это достигается опросом всех обработчиков данного уровня приоритета, пока один из них не подтвердит, что прерывание пришло от обслуживаемого им устройства. В случае одного устройства определение нужного обработчика происходит немедленно, как и при векторном прерывании. Опрашиваемые прерывания поддерживают шины ISA, EISA, PCI, MCA.
Механизм прерываний некоторой аппаратной платформы может сочетать оба типа прерываний. Выше приведены примеры шин, поддерживающих механизм опрашиваемых прерываний. Контроллеры периферийных устройств выставляют на шину не вектор, а сигнал запроса определенного уровня IRQ. Однако в процессоре Pentium система прерываний является векторной. Вектор прерываний в процессор поставляется контроллером прерываний, отображающим сигнал IRQ на определенный номер вектора. Вектор передается в процессор в виде целого числа в диапазоне (0…255), указывающего на один из 256 обработчиков, адреса которых хранятся в таблице.
Чтобы не допустить нежелательную обработку прерываний, их можно маскировать.
46
3.4. Системные вызовы
Обобщенно последовательность действий диспетчера прерываний можно описать следующим образом:
1.При возникновении сигнала или условия прерывания происходит первичная обработка: анализ причин прерывания, выбор программы, которая должна реагировать на прерывание. Если прерывание данного типа в настоящий момент запрещено, то процессор продолжает естественный ход выполнения команд. В противном случае происходит автоматический выбор обработчика из специальной таблицы ОС, размещаемой либо в регистрах, либо в определенном месте ОП.
2.Сохраняется часть контекста прерванного потока, которая позволит ядру возобновить исполнение потока процесса после обработки прерывания. В эту информацию обычно включаются значения счетчика команд, слова состояния машины (регистр EFLAGS в Pentium), а также те регистры общего назначения, которые требуются обработчику.
3.Одновременно с загрузкой адреса обработчика в счетчик команд может выполняться и загрузка нового значения слова состояния машины (селектора кодового сегмента в процессоре Pentium), которое определяет режимы работы процессора при обработке прерывания.
4.Временно запрещаются прерывания данного типа, чтобы не образовалась очередь вложенных друг в друга потоков одной и той же процедуры с помощью маскирования прерываний.
5.После того как прерывание обработано ядром, прерванный контекст восстанавливается, и работа потока возобновляется с прерванного места. Контекст восстанавливается аппаратно командой возврата из прерывания (например, адрес следующей команды и слово состояния машины), а часть – программно с извлечением данных из стека. Блокировка прерываний данного типа снимается.
3.4. Системные вызовы
Системный вызов позволяет приложению обратиться к ОС с просьбой выполнить то или иное действие, оформленное как процедура кодового сегмента ОС. В этом плане для прикладного программиста ОС представляется некоторой библиотекой, имеющей набор различных функций, с помощью которых можно упростить прикладную програм-
47
3. Управление процессами и потоками
му или выполнить действия, запрещенные в пользовательском режиме, например обмен данными с устройством ввода-вывода.
Системные вызовы могут обслуживаться децентрализованно
ицентрализованно. Первый способ закрепляет за каждым вызовом определенное значение вектора прерываний. Приложение при таком способе вызова непосредственно указывает в аргументе запроса значение вектора, после чего управление немедленно передается требуемой процедуре ОС. Однако такой способ привязан к аппаратной платформе и не позволяет ОС легко модифицировать набор системных вызовов
иконтролировать их использование.
Вбольшинстве ОС системные вызовы обслуживаются по централизованной схеме, основанной на существовании диспетчера системных вызовов. При любом системном вызове приложение выполняет программное прерывание с определенным и единственным номером вектора (вWinNTинструкция INT2Eh). Номер системного вызова передается ОС. Этот номер является индексом в таблице адресов процедур ОС, реализующих системные вызовы. Номер и аргументы системного вызова помещаются в регистры либо в системный стек, так как происходит переход в привилегированный режим. Диспетчер представляет собой программу, сохраняющую содержимое регистров в системном стеке, проверяет попадание номера вызова в диапазон и передает управление процедуре ОС, адрес которой находится в таблице адресов системных вызовов. Процедура реализации системного вызова извлекает из системного стека аргументы и выполняет заданное действие (чтение системных часов, чтение файла). После завершения работы системного вызова управление возвращается диспетчеру, при этом он получает код возврата. Диспетчер восстанавливает регистры процессора, помещает в определенный регистр код возврата и выполняет инструкцию возврата из прерывания, которая восстанавливает пользовательский режим.
Дляприложениясистемныйвызоввнешненичемнеотличаетсяот вызова обычной функции языка Си. Программист имеет дело с набором функций API, часть из которых используется системными вызовами, а часть – нет.
ОС может выполнять системные вызовы в синхронном и асинхронном режимах. Синхронный системный вызов означает, что процесс блокируется до тех пор, пока вызов не выполнит всю свою работу. Затем
48
3.5. Синхронизация процессов и потоков
процесс переводится в состояние готовности и при очередном выполнении может воспользоваться результатами завершившегося системного вызова. Синхронные вызовы называются еще блокирующими. Большинство системных вызовов в ОС являются синхронными.
Асинхронный системный вызов не блокирует процесс, так как после выполнения некоторых начальных системных действий, например запуска операции ввода-вывода, управление возвращается прикладному процессу. Такой режим работы характерен для ОС на основе микроядерной архитектуры.
3.5. Синхронизация процессов и потоков
Существует обширный класс средств ОС, с помощью которых обеспечивается взаимная синхронизация процессов и потоков. Потребность в синхронизации потоков связана с совместным использованием ресурсов ВС. Синхронизация необходима для исключения гонок и тупиков при обмене данными между потоками, разделении данных, доступе к процессору и устройствам ввода-вывода.
ВомногихОСэтисредстваназываютсясредствамимежпроцессного взаимодействия IPC. Обычно к ним относят не только средства межпроцессной синхронизации, но и средства межпроцессного обмена данными.
Параллельные потоки могут работать совершенно независимо друг от друга или должны взаимодействовать друг с другом. Синхронизация заключается в согласовании скоростей процессов и потоков путем приостановки потока до наступления некоторого события и последующей его активизации при наступлении этого события. ОС может предоставлять широкий спектр средств синхронизации.
Когда к одним данным осуществляется доступ со стороны нескольких параллельных потоков, могут возникнуть ошибки. Этого можно избежать, если каждому потоку предоставлять монопольное право доступа к переменной. Когда один поток работает с ней, всем остальным приходится ждать, и когда данный поток закончит свое обращение к переменной, выполнять свою работу будет разрешено одному из потоков, находящихся в ожидании. Таким образом, каждый из потоков, обращающийся к разделяемым данным, исключает для всех других по-
49
3. Управление процессами и потоками
токов возможность одновременного с ним обращения к этим данным. Это называется взаимоисключением. Гонки – ситуация, в которой два или более потока обрабатывают разделяемые данные, и конечный результат зависит от соотношения скоростей потоков.
Важным понятием синхронизации является понятие «критической секции» программы. Критическая секция – это часть программы, результат выполнения которой может непредсказуемо меняться, если переменные, относящиеся к этой части программ, изменяются другими потоками в то время, когда выполнение этой части еще не завершено. Критическая секция всегда определяется по отношению к определенным критическим данным, при несогласованном изменении которых могут возникнуть нежелательные эффекты. Во всех потоках, работающих с критическими данными, должна быть определена критическая секция, в общем случае состоящая из разных последовательностей команд. Взаимное исключение позволяет обеспечить нахождение только одного потока в критической секции.
3.5.1. Блокирующие переменные
Для синхронизации потоков одного процесса программист может использовать глобальные блокирующие переменные. С этими переменными, к которым все потоки имеют прямой доступ, программист работает, не обращаясь к системным вызовам ОС. Каждому набору критических данных ставится в соответствие двоичная переменная. Поток может войти в критическую секцию, когда значение блокирующей переменной равно 0, одновременно изменяя ее значение на 1. При выходе из критической секции поток сбрасывает значение блокирующей переменной в 0. Недостаток: во время нахождения одного потока в критической секции другой поток, требующий тот же ресурс, получив доступ к процессору, будет непрерывно опрашивать блокирующую переменную, бесполезно затрачивая процессорное время. Для устранения этого недостатка во многих ОС предусмотрены специальные системные вызовы для работы с критическими секциями.
3.5.2. Семафоры
Обобщением блокирующих переменных являются так называемые семафоры Дейкстры. Вместо двоичных переменных Дейкстра
50
