Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2-52.docx
Скачиваний:
6
Добавлен:
23.09.2019
Размер:
183.92 Кб
Скачать

43, Синхронизация

Синхронизация

Концепция взаимоисключения (mutual exclusion) является одной из ключевых при разработке операционных систем. Ее смысл в следующем: в каждый момент к конкретному ресурсу может обращаться один — и только один — поток. Взаимоисключение необходимо, когда ресурс не предназначен для разделения или когда такое разделение может иметь непредсказуемые последствия.

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

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

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

Синхронизация ядра при высоком IRQL

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

44, Спин-блокировки

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

Спин-блокировки

Механизм, применяемый ядром для взаимоисключения в многопроцессорных системах, называется спин-блокировкой (spinlock). Спин-блокировка — это блокирующий примитив, сопоставленный с какой-либо глобальной структурой данных вроде очереди DPC

спин-блокировка - простейший механизм синхронизации. спин-блокировка может быть захвачена, и освобождена. если спин-блокировка была захвачена, последующая попытка захватить спин-блокировку любым потоком приведет к бесконечному циклу с попыткой захвата спин-блокировки (состояние потока busy-waiting). цикл закончится только тогда, когда прежний владелец спин-блокировки освободит ее. использование спин-блокировок безопасно на мультипроцессорных платформах, то есть гарантируется, что, даже если ее запрашивают одновременно два потока на двух процессорах, захватит ее только один из потоков. спин-блокировки предназначены для защиты данных, доступ к которым производится на различных, в том числе повышенных уровнях irql. теперь представим такую ситуацию: код, работающий на уровне irql passive_ level захватил спин-блокировку для последующего безопасного изменения некоторых данных. после этого код был прерван кодом с более высоким уровнем irql dispatch_level, который попытался захватить ту же спин-блокировку, и, как следует из описания спин-блокировки, вошел в бесконечный цикл ожидания освобождения блокировки. этот цикл никогда не закончится, так как код, который захватил спин-блокировку и должен ее освободить, имеет более низкий уровень irql и никогда не получит шанса выполниться! чтобы такая ситуация не возникла, необходим механизм, не позволяющий коду с некоторым уровнем irql прерывать код с более низким уровнем irql в тот момент когда код с более низким уровнем irql владеет спин-блокировкой. таким механизмом является повышение текущего уровня irql в момент захвата спин-блокировки до некоторого уровня irql, ассоциированного со спин-блокировкой, и восстановление старого уровня irql в момент ее освобождения. из сказанного следует, что код, работающий на повышенном уровне irql, не имеет права обращаться к ресурсу, защищенному спин-блокировкой, если уровень irql спин-блокировки ниже уровня irql производящего доступ к ресурсу кода. при попытке таким кодом захватить спин-блокировку его уровень irql будет понижен до уровня irql спин-блокировки, что приведет к непредсказуемым последствиям. в nt имеется два вида спин-блокировок:

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

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