Операционные системы -вопросы теории

       

Примитивы синхронизации



Примитивы синхронизации

Я слышу крик в темноте
Наверное, это сигнал.
В. Бутусов

Посмотрев на примеры 7.2 и 7.4, внимательный читатель должен отметить, что используемая конструкция подозрительно похожа на работу с внешними устройствами в режиме опроса. Действительно, опрос флаговой переменном в цикле хотя и обеспечивает гарантию взаимоисключения, но обладает всеми недостатками, которые мы указывали для опроса внешнего устройства.
g случае исполнения параллельных нитей на одном процессоре, данный метод имеет еще один недостаток: пока одна из нитей занимается опросом, никакая другая нить не может исполняться, потому что процессор загружен непродуктивной работой.
Легко видеть, что в данном случае использование прерываний или какого-то их аналога проблемы не решит: в лучшем случае, "прерывание" будет вызываться не в той нити, в которой нужно, сводя задачу взаимоисключения к предыдущей, только с уже новой флаговой переменной, а в худшем — приведет к возникновению еще одной нити. Задача взаимодействия между асинхронными нитями, таким образом, сводится к требованию того, чтобы нити в какие-то моменты переставали быть асинхронными, синхронизовались.
Если у нас уже есть примитив взаимного исключения, мы можем решить задачу синхронизации, предоставив еще один примитив, который позволяет активному процессу остановиться, ожидая, пока флаговая переменная не примет "правильное" значение, и продолжить исполнение после этого. При обработке прерываний роль такого примитива может исполнять команда остановки процессора: у всех современных процессоров прерывание останавливает "исполнение" этой команды, а возврат из обработчика передает управление на следующую команду, таким образом выводя процессор из спящего состояния. В многопроцессорной конфигурации можно ввести средство, при помощи которого один процессор может вызывать прерывание другого — и тогда каждый из процессоров системы сможет ожидать другого, переходя в режим сна. При реализации же многопоточностп на одном процессоре (см. разд. Вытесняющая многозадачность) примитив засыпания (блокировки) нити должен предоставляться модулем, ответственным за переключение потоков.
Впрочем, если операции над флагом, засыпание потока и его пробуждение реализованы разными примитивами, мы рискуем получить новую проблему (пример 7.5). Она состоит в том, что если пробуждающий сигнал поступит в промежутке между операторами testandset и pause, мы его не получим. В результате операция pause приведет к засыпанию нашей нити навсегда.



Содержание раздела