Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
196
Добавлен:
20.02.2016
Размер:
115.2 Кб
Скачать

Лекция №11. Механизмы синхронизации

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

[11.1] Спин-блокировки

Спин-блокировка – простейший механизм синхронизации. Спин-блокировка может быть захвачена, и освобождена. Если спин-блокировка была захвачена, последующая попытка захватить спин-блокировку любым потоком приведет к выполнению бесконечного цикла с попыткой захвата спин-блокировки (состояние потока busy-waiting). Цикл закончится только тогда, когда прежний владелец спин-блокировки освободит ее. Использование спин-блокировок безопасно на мультипроцессорных платформах, т.е. гарантируется, что, даже если ее запрашивают одновременно два потока на двух процессорах, захватит ее только один из потоков.

Спин-блокировки предназначены для защиты данных, доступ к которым производится на различных, в т.ч. повышенных уровнях IRQL. Теперь представим такую ситуацию: код, работающий на уровне IRQL PASSIVE_LEVEL захватил спин-блокировку для последующего безопасного изменения некоторых данных. После этого код был прерван кодом с более высоким уровнем IRQL DISPATCH_LEVEL, который попытался захватить ту же спин-блокировку, и, как следует из описания спин-блокировки, вошел в бесконечный цикл ожидания освобождения блокировки. Этот цикл никогда не закончится, т.к. код, который захватил спин-блокировку и должен ее освободить, имеет более низкий уровень IRQL и никогда не получит шанса выполниться! Чтобы такая ситуация не возникла, необходим механизм, не позволяющий коду с некоторым уровнем IRQL прерывать код с более низким уровнем IRQL в тот момент когда код с более низким уровнем IRQL владеет спин-блокировкой. Таким механизмом является повышение текущего уровня IRQL в момент захвата спин-блокировки до некоторого уровня IRQL, ассоциированного со спин-блокировкой, и восстановление старого уровня IRQL в момент ее освобождения. Из сказанного следует, что код, работающий на повышенном уровне IRQL, не имеет права обращаться к ресурсу, защищенному спин-блокировкой, если уровень IRQL спин-блокировки ниже уровня IRQL производящего доступ к ресурсу кода. При попытке таким кодом захватить спин-блокировку его уровень IRQL будет понижен до уровня IRQL спин-блокировки, что приведет к непредсказуемым последствиям.

В NT имеется 2 вида спин-блокировок:

  • Обычные спин-блокировки, особым случаем которых являются спин-блокировки отмены запроса в/в, используемые при организации очередей запросов в/в (см. лекцию 10 п. [10.3] Отмена запросов в/в).

  • Спин-блокировки синхронизации прерываний

С обычными спин-блокировками связан IRQL DISPATCH_LEVEL, т.е.

  1. все попытки их захвата должны производиться на уровне IRQL<=DISPATCH_LEVEL

  2. в случае захвата спин-блокировки текущий уровень IRQL поднимается до уровня DISPATCH_LEVEL.

Со спин-блокировками синхронизации прерываний связан один из уровней DIRQL.

Использование обычных спин-блокировок будет описано ниже (за исключением спин-блокировок отмены запросов в/в, которые были описаны в разделе 10.3).

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

Соседние файлы в папке Лабы по драйверам