Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 700363.doc
Скачиваний:
16
Добавлен:
01.05.2022
Размер:
3.69 Mб
Скачать

Недостатки алгоритмов с активным ожиданием

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

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

Алгоритмы взаимоисключения с блокировкой процессов

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

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

Синхронизирующий объект может быть определен, например, следующим образом.

struct SyncObject { int count; // счетчик оставшихся захватов struct WaitQueue { // элемент очереди // ожидающих процессов WaitQueue *next; // указатель на // следующий элемент очереди PROCESS_POINTER proc; // указатель на // контекст процесса, // ожидающего доступ } *proc_list; // голова списка ожидающих процессов };

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

Семафор Дейкстры содержит счетчик показывающий, сколько еще процессов могут получить доступ к данному ресурсу. Начальное значение счетчика устанавливается при создании объекта синхронизации. Если ресурс не может разделяться несколькими процессами одновременно (требуется доступ в режиме взаимного исключения), то начальное значение счетчика должно быть равно единице.

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

Для работы с объектами синхронизации необходимы как минимум следующие четыре системных вызова, называемых примитивами синхронизации.

  • системный вызов для получения доступа к примитиву синхронизации из пользовательской программы (открытие объекта синхронизации);

  • системный вызов для отказа от доступа к объекту синхронизации, который больше не требуется процессу (закрытие объекта синхронизации)

  • системный вызов для захвата объекта синхронизации процессом (вхождение в критическую секцию)

  • системный вызов для освобождения ранее захваченного объекта синхронизации (выход из критической секции)

Рассмотрим перечисленные примитивы синхронизации более внимательно.