27.
Реализация взаимного исключения с
использованием системных функций входа в критическую секцию и выхода из нее.
На
рис. 6.1.4 показано, как с помощью этих
функций реализовано взаимное исключение в операционных системах семейства Windows NT. Перед тем как начать изменение критических
данных, поток выполняет системный вызов EnterCriticalSection().
В рамках этого вызова сначала выполняется, как и в предыдущем случае, проверка
блокирующей переменной, отражающей состояние критического ресурса. Если
системный вызов определил, что ресурс занят (F(D) - 0), он в отличие от
предыдущего случая не выполняет циклический опрос, а переводит поток в
состояние ожидания D) и делает отметку о том, что данный поток должен быть
активизирован, когда соответствующий ресурс освободится. Поток, который в это
время использует данный ресурс, после выхода из критической секции должен
выполнить системную функцию LeaveCriticalSection(), в результате чего
блокирующая переменная принимает значение, соответствующее свободному состоянию
ресурса (F(D) - 1), а операционная система просматривает очередь ожидающих этот
ресурс потоков и переводит первый поток из очереди в состояние готовности.
Рис. 6.1.4. Реализация взаимного исключения с использованием системных функций входа в критическую секцию и выхода из нее
Таким
образом исключается непроизводительная потеря процессорного времени на
циклическую проверку освобождения занятого ресурса. Однако в тех случаях, когда
объем работы в критической секции небольшой и существует высокая вероятность в
очень скором доступе к разделяемому ресурсу, более предпочтительным может
оказаться использование блокирующих переменных. Действительно, в такой ситуации
накладные расходы ОС по реализации функции входа в критическую секцию и выхода
из нее могут превысить полученную экономию.