
ОС / учебник(см. лекции) Корольковой / глава 2
.pdf
Схема назначения приоритета потокам в Windows 2000
Как показано на Рис. 2.6, в Windows 2000 предусмотрено 32 уровня приоритета — от
0 до 31. Эти значения группируются так:
-шестнадцать уровней реального времени (16-31);
-пятнадцать варьируемых (динамических) уровней (1-15);
-один системный уровень (0), зарезервированный для потока обнуления страниц .
-16 уровней реального времени.
Рис. 2.6 Уровни приоритета потоков
Уровни приоритета потока назначаются с учетом двух разных точек зрения -Win32 API и ядра Windows 2000. Win32 API сначала упорядочивает процессы по классам приоритета, назначенным при их создании (реального времени, высокий, выше обычного,
обычный, ниже обычного и простаивающий), а затем — по относительному приоритету индивидуальных потоков в рамках этих процессов (критичный по времени, наивысший,
выше обычного, обычный, ниже обычного, наименьший и простаивающий). Приоритет каждого потока в Win32 API устанавливается, исходя из класса приоритета его процесса и относительного приоритета самого потока. Связь между приоритетами Win32 и
внутренними приоритетами Windows 2000 в числовой форме показана на Рис. 2.8.
Приоритеты, показанные на Рис. 2.8, являются базовыми для потоков. Сначала потоки наследуют базовый приоритет процесса. Обычно базовый приоритет процесса по умолчанию равен значению из середины диапазонов приоритетов процессов (24, 13, 10, 8,
б или 4).Если у процесса только одно значение приоритета (базовое), то у каждого потока их два: текущее и базовое. Текущий приоритет для потоков в динамическом диапазоне (1-
15) может быть выше базового, что обычно и бывает. Windows 2000 никогда не изменяет приоритеты потоков в диапазоне реального времени (16-31), поэтому у таких потоков базовый приоритет идентичен текущему.

Рис. 2.7 Приоритеты в ядре и Win32
3.Гарантированное планирование
Всистеме с n-процессами, каждому процессу будет предоставлено 1/n времени процессора.
ОС отслеживает распределение процессорного времени между потоками с момента создания каждого потока и вычисляет отношение времени, предоставленного потоку, к
времени, на которое он имеет право (время с момента создания, деленное на n). Если это отношение меньше 1, то поток недополучил процессорное время. На выполнение запускается поток с наименьшим значением этого отношения.
4. Лотерейное планирование Процессам раздаются "лотерейные билеты", дающие право доступа к ресурсам.
Планировщик может выбрать любой билет случайным образом. Чем больше билетов у процесса, тем больше у него шансов захватить ресурс. Взаимодействующие процессы могут при необходимости обмениваться билетами.
5. Справедливое планирование Процессорное время распределяется среди процессов, а не потоков. Это
справедливо, если у одного процесса несколько потоков, а у другого один.
2.4.6 Планирование в системах реального времени ОС реального времени предназначены для управления различными техническими
объектами или технологическими процессами. В таких системах мультипрограммная

смесь обычно представляет собой фиксированный набор заранее разработанных
программ, а выбор программы на выполнение осуществляется по прерываниям (исходя из состояния управляемого объекта) или в соответствии с расписанием плановых работ.
Критерий эффективности работы ОС реального времени – способность системы выдерживать заранее заданные интервалы времени между запуском программы и получением результата (реактивность системы).
Системы реального времени делятся на:
-жесткие - несоблюдение временных ограничений приводит к катастрофическим последствиям; в таких системах время завершения выполнения каждой из критических задач должно быть гарантировано для всех возможных сценариев работы системы;
-гибкие - нарушения временного графика нежелательны, но допустимы, это позволяет использовать менее затратные способы планирования.
Внешние события, на которые система должна реагировать, делятся:
-периодические – начиная с момента первоначального запроса все будущие моменты возникновения задачи можно определить заранее;
-спорадические - моменты возникновения запросов заранее неизвестны.
Для того, что бы систему реального времени можно было планировать, необходимо,
чтобы выполнялось условие:
где m - число периодических событий, i - номер события, P(i) - период поступления события, T(i) - время, которое уходит на обработку события.
2.5 Взаимодействие между процессами
2.5.1 Виды взаимодействий между процессами Процессам приходится взаимодействовать в следующих ситуациях:
-передача информации от одного процесса другому;
-контроль над деятельностью процессов (например, когда они борются за один ресурс);
-согласование действий процессов (например, когда один процесс поставляет данные, а другой их выводит на печать; если согласованности не будет, то второй процесс может начать печать раньше, чем поступят данные).
Два из трех описанных пунктов в равной степени относятся и к процессам и к потокам. В первом случае у потоков не возникает проблем, т.к. они разделяют общее адресное пространство.

2.5.2 Синхронизация процессов и потоков
2.5.2.1Состязания (гонки)
2.5.2.1.1Ситуация состязания
Состязания – ситуация, когда два или более потоков обрабатывают разделяемые данные и конечный результат зависит от соотношения скоростей потоков.
Рассмотрим пример
Рис. 2.8 Возникновение гонок при доступе к разделяемым ресурсам
Рис. 2.9 Влияние относительных скоростей потоков на результат решения задачи
2.5.2.1.2 Критические секции Критическая секция - часть программы, результат выполнения которой может
непредсказуемо меняться, если переменные, относящиеся к этой части программы,
изменяются другими потоками в то время, когда выполнение этой части еще не завершено. Критическая секция всегда определяется по отношению к критическим данным.

Чтобы исключить эффект гонок по отношению к критическим данным, необходимо реализовать взаимное исключение – в критической секции, связанной с этими данными,
может находиться только один поток (в активном или приостановленном состоянии).
2.5.3.1.3 Способы реализации взаимного исключения
1. Запрет прерываний Заключается в запрещении всех прерываний процесса при входе в критическую
секцию. Практически не применяется, так как ОС лишается возможности снять поток с выполнения в случае его некорректной работы.
2. Блокирующие переменные Каждому набору критических данных ставится в соответствие глобальная двоичная
переменная. Перед входом в критическую секцию поток проверяет, не работает ли уже какой-нибудь поток с данными (по состоянию блокирующей переменной), если данные свободны – сбрасывает блокирующую переменную, входит в критическую секцию, перед завершением – устанавливает ее (Рис. 2.10). Если данные заняты – проверка циклически повторяется. Взаимное исключение гарантировано, если все потоки, разделяющие данные,
написаны по этому соглашению.
Нельзя прерывать поток между операцией проверки и установки блокирующей переменной. Необходимо использовать единую, неделимую операцию проверки и присвоения значения логической переменной (например, BTS, BTR, BTC
микропроцессора Pentium).
Рис. 2.10 Реализация критических секций с использованием блокирующих переменных Поток, пытающийся получить доступ к занятым данным, будет непрерывно
опрашивать блокирующую переменную, бесполезно тратя процессорное время. Решение

– во многих ОС предусмотрены специальные системные вызовы для работы с критическими секциями, которые переводят поток, запросивший доступ к занятым данным, в состояние ожидания.
3. Семафоры Семафоры – переменные, которые могут принимать целые неотрицательные
значения и используются для синхронизации вычислительных процессов.
Для работы с семафорами определены два примитива:
V(S): переменная S увеличивается на 1 единым действием;
P(S): уменьшение S на 1, если это возможно; если это невозможно, то поток, вызвавший
P(S) переводится в состояние ожидания до тех пор, пока это не станет возможным.
Решение проблемы «читатели – писатели» с помощью семафоров Рассмотрим использование семафоров на классическом примере взаимодействия
двух процессов, выполняющихся в режиме мультипрограммирования, один из которых пишет данные в буферный пул, а другой считывает их из буферного пула. Пусть буферный пул состоит из N буферов, каждый из которых может содержать одну запись.
Процесс "писатель" должен приостанавливаться, когда все буферы оказываются занятыми, и активизироваться при освобождении хотя бы одного буфера. Напротив,
процесс "читатель" приостанавливается, когда все буферы пусты, и активизируется при появлении хотя бы одной записи.
Введем два семафора: e - число пустых буферов и f - число заполненных буферов.
Запись в буфер и считывание из буфера являются критическими секциями. Работу потоков с общим буферным пулом иллюстрирует рис.2.10.
Рис. 2.11 Использование семафоров для синхронизации потоков
2.5.2.2 Взаимные блокировки
2.5.2.2.1 Ситуация взаимной блокировки

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

предотвращение тупиков,
распознавание тупиков,
восстановление системы после тупиков.
Условия, необходимые для возникновения взаимоблокировки:
1.Условие взаимного исключения - в какой-то момент времени, ресурс занят только одним процессом или свободен.
2.Условие удержания и ожидания - процесс, удерживающий ресурс может запрашивать новые ресурсы.
3.Условие отсутствия принудительной выгрузки ресурса.
4.Условие циклического ожидания - должна существовать круговая последовательность из процессов, каждый, из которого ждет доступа к ресурсу,
удерживаемому следующим членом последовательности.
2.5.2.2.2 Моделирование взаимоблокировок Моделирование тупиков с помощью графов.
Рис. 2.13 Условные обозначения На такой модели очень легко увидетьть, возникает ли взаимоблокировка. Если есть
цикл, значит, есть и взаимоблокировка.
Рассмотрим пример:
три процесса A, B, C
три ресурса R, S, T
Последовательное выполнение процессов, взаимоблокировка не возникает Рассмотрим циклический алгоритм:
три процесса A, B, C

три ресурса R, S, T
Рис. 2.14 Возникает взаимоблокировка Рассмотрим тот же самый случай, но допустим, что система, зная о предстоящей
взаимоблокировке, заблокирует процесс B.
Рис. 2.15 Взаимоблокировка не возникает
2.5.2.3 Методы борьбы с тупиками
2.5.2.3.1 Пренебрежением проблемой в целом (страусовый алгоритм)
Если вероятность взаимоблокировки очень мала, то ею легче пренебречь, т.к. код исключения может очень усложнить ОС и привести к большим ошибкам. Также многие взаимоблокировки тяжело обнаружить.
Этот алгоритм используется как в UNIX, так и в Windows.
Поэтому на серверах часто устанавливают автоматическую перезагрузку (раз в сутки, как правило, ночью), если возникнет взаимоблокировка, то после перезагрузки ее не будет.
2.5.2.3.2 Обнаружение и устранение взаимоблокировок Система не пытается предотвратить взаимоблокировку, а пытается обнаружить ее и
устранить.
2.5.2.3.3 Обнаружение взаимоблокировки при наличии одного ресурса каждого типа

Под одним ресурсом каждого типа, подразумевается один принтер, один сканер и один плоттер и т.д.
Рассмотрим систему из 7-ми процессов и 6-ти ресурсов.
Визуально хорошо видна взаимоблокировка, но необходимо, чтобы ОС сама определяла взаимоблокировку.
Рассмотрим один из алгоритмов.
Для каждого узла N в графе выполняется пять шагов.
1.Задаются начальные условия: L-пустой список, все ребра не маркированы.
2.Текущий узел добавляем вконец списка L и
проверяем количество появления узла в списке. Если он встречается два раза, значит цикл и взаимоблокировка.
Рис. 2.16 Обнаружение взаимоблокировки при наличии одного ресурса каждого типа
3.Для заданного узла смотрим, выходит ли из него хотя бы одно немаркированное ребро. Если да, то переходим к шагу 4, если нет, то переходим к шагу 5.
4.Выбираем новое немаркированное исходящее ребро и маркируем его. И
переходим по нему к новому узлу и возвращаемся к шагу 3.
5.Зашли в тупик. Удаляем последний узел из списка и возвращаемся к предыдущему узлу. Возвращаемся к шагу 3. Если это первоначальный узел, значит,
циклов нет, и алгоритм завершается.
Рис. 2.17 Алгоритм обнаружения взаимоблокировок
Для приведенного случая тупик обнаруживается в списке L=[B,T,E,V,G,U,D,T]. 2.5.2.3.4 Обнаружение взаимоблокировки при наличии нескольких ресурсов каждого
типа
Рассмотрим систему, в которой