Если сравнить семафоры с традиционными механизмами ОС, основанными на приостановке-возобновлении выполнения, то станет видно, что первые обладают определенным преимуществом, связанным с возобновлением выполнения дополнительных процессов.
Если процесс был разбужен в результате операции Р(), то он гарантированно получит необходимый ресурс. Семантика вызова гарантирует передачу пробуждаемой нити прав владения семафором до начала его выполнения. Если в этот промежуток времени иная нить попытается запросить тот же семафор, то она потерпит неудачу. Однако такое свойство семафоров приводит к возникновению проблемы, названной конвоированием семафоров [12]. Конвой возникает в случае частого обращения к семафору. Это может уменьшить производительность любого механизма блокировки, но особенность семантики семафоров значительно усложняет возникающую проблему.
Ранее показан пример формирования конвоирования. Р1 — это критический участок кода, защищенный семафором. На стадии а семафор удерживается нитью Н2, а нить НЗ находится в режиме его ожидания. Нить Н1 выполняется на другом процессоре системы, в то время как Н4 находится в очереди планирования. Теперь представьте, что Н2 завершает выполнение критической секции и освобождает семафор. Тогда она разбудит нить НЗ и перенесет ее в очередь планировщика. Теперь семафор удерживает нить НЗ (как это показано ранее.
Пример формирования конвоев
Затем выполнение критического участка кода необходимо начать нити Н1. Так как семафор в текущий момент удерживается нитью НЗ, Н1 будет заблокирована и освободит процессор П1. Система направит нить Н4 на выполнение на этом процессоре. Таким образом, на этапе в семафор удерживает нить НЗ, Н1 ожидает его освобождения, а нити Н2 и Н4 могут выполняться до тех пор, пока сами не освободят занимаемые ими процессоры.
Проблема возникает именно на этой стадии. Семафор был присвоен нити НЗ, но она в данный момент не выполняется и, следовательно, не находится в критической области. В результате нить Н1 должна быть заблокирована в ожидании семафора, несмотря на то, что ни одна из нитей не выполняет критичный участок кода. Семантика команд работы с семафорами предоставляет ресурсы по принципу: «кто первым пришел, тот и будет обслужен». Такой подход приводит к большому количеству ненужных переключений контекста. Представьте ситуацию, в которой вместо семафора используется объект mutex (взаимное исключение). Тогда на стадии б нить Н2 должна освободить объект и разбудить ИЗ. Но последняя не является на этой стадии владельцем объекта. Следовательно, на следующем этапе объект будет пытаться получить нить Н1, что исключит переключение контекста.
Mutex, или взаимное исключение (сокращение от mutual exclusion lock), является общим термином, обозначающим любой примитив, приводящий к семантике эксклюзивного доступа.’
Из сказанного можно сделать вывод, что наиболее предпочтительным является применение вместо единого монолитного объекта высшего уровня простых в обращении элементов низшего уровня. Именно этой идеей руководствуются разработчики ядра современных многопроцессорных систем. Следующие разделы будут посвящены описанию механизмов низшего уровня, создающих вместе гибкую систему синхронизации.
Опубликовал katy
July 06 2015 16:19:29 ·
0 Комментариев ·
2049 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.