Добавлен: 20.10.2018
Просмотров: 657
Скачиваний: 6
Это позволит одному из них (кого выберет планировщик) войти в свою
критическую секцию и тем самым, возможно, блокировать другие потоки.
Еще одним интересным способом синхронизации потоков являются
мониторы. Мониторы могут встраиваться в языки программирования
высокого уровня, что позволяет переносить решение многих непростых
вопросов организации взаимодействия потоков на уровень компиляторов.
Современная реализация мониторов предполагает использование объектно-
ориентированнной технологии и встраивания в соответствующие языки.
При организации взаимодействия потоков есть одна весьма серьезная
опасность: попадание двух или нескольких потоков в состояние взаимной
блокировки или тупика (deadlock). Эту ситуацию можно показать на
следующем примере.
Пусть в соответствии со своей внутренней логикой поток 1 должен начать
работу сначала с файлом А, а потом (не завершив эту работу) – с файлом В.
Пусть поток 2, наоборот, сначала начинает работу с файлом В, а потом – с
файлом А. При этом возможна следующая последовательность действий:
поток 1 начал работу с файлом А и блокировал его, после чего поток 1
был прерван;
поток 2 начал свою работу с файлом В и блокировал его, после чего
был прерван;
поток 1 возобновляет свою работу, запрашивает файл В, но тот занят
потоком 2 и поэтому поток 1 переводится в состояние ожидания;
поток 2 возобновляет свою работу, запрашивает файл А, но тот занят
потоком 1, и поэтому поток 2 тоже переводится в состояние ожидания.
В итоге оба потока переходят в состояние взаимного ожидания и не могут
освободить свои занятые файлы и тем самым продолжить нормальную
работу. Ясно, что в тупиковую ситуацию может попасть одновременно и
несколько потоков. При этом вместо файлов может выступать любой
разделяемый ресурс, как физический, так и логический.
Для борьбы с тупиковыми ситуациями было предложено множество
методов. Видимо, наиболее интересным методом является полное
игнорирование данной ситуации, что, впрочем, объясняется очень маленькой
вероятностью возникновения тупика. Здесь работает хорошо известный
принцип практической уверенности: очень маловероятное событие можно
считать невозможным. Дело в том, что затраты на анализ и устранение
ситуации взаимной блокировки могут быть достаточно большими, поэтому
разработчики ОС должны сопоставить эти затраты с тем потенциальным
вредом, который может принести возникновение данной ситуации.
Вторая группа методов позволяет возникнуть взаимоблокировке, а потом
устранить эту ситуацию. Для обнаружения подобной ситуации разработан
ряд алгоритмов, основанных на методах теории графов. Эти алгоритмы
можно запускать с некоторой периодичностью и после обнаружения
deadlock’а применить один из следующих методов устранения:
уничтожить один или (если требуется) несколько потоков;
выполнить откат одного из заблокированных потоков, т.е. вернуть его
к состоянию ДО запроса ресурса;
принудительно отобрать ресурс у его владельца и отдать другому
потоку.
Наконец, третья группа методов старается вообще избежать
возникновения ситуации взаимной блокировки и включает в себя следующие
подходы:
при наличии достаточной исходной информации об имеющихся
ресурсах и потоках можно построить безопасную траекторию
выделения ресурсов, что на практике, к сожалению, практически
нереализуемо;
минимизация числа потоков, претендующих в каждый момент времени
на тот или иной ресурс, т.е. уменьшение вероятности возникновения
deadlock’а;
при запросе потоком нового ресурса он должен сначала освободить все
используемые им ресурсы, а уж потом получить все, что надо;
пронумеровать и упорядочить все ресурсы и выделять их строго в
возрастающем порядке.
Видно, что предлагаемые методы достаточно трудоемки, поэтому на
практике часто применяют подход, когда сама система может устранять
тупики за счет отслеживания времени пребывания потоков в состоянии
ожидания, и если это время начинает превышать некоторый допустимый
предел, можно принудительно освободить взаимно блокированные ресурсы.