Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Метода Процессы и потоки.doc
Скачиваний:
7
Добавлен:
14.07.2019
Размер:
401.92 Кб
Скачать

Объекты синхронизации

В связи с тем что Windows 9.x и Windows NT/2000 присуща вытесняющая многоза­дачность, возможность доступа двух нитей к одной и той же области памяти внутри процесса оказывается проблематичной. Некоторые нити не имеют доступа к памяти либо выполняют операции, которые оказывают влияние на другие нити внутри процес­са. Однако если нити не разделяют общие ресурсы процесса или системные ресурсы, либо они должны выполняться согласованно, то в этом случае требуется определенная их синхронизация. Для совместной работы нитей без разрушения памяти в интерфей­се Win32 API предоставляются объекты синхронизации (synchronization objects). Объекты синхронизации обеспечивают доступ к системным ресурсам, которые могут находить­ся под управлением нитей одних и тех же либо других процессов.

Тремя основными типами объектов синхронизации являются мьютексы, семафо­ры и события. Эти объекты синхронизации отличаются друг от друга условием уста­новки сигнального состояния. Наиболее распространенные объекты синхронизации перечислены в табл. 1.

Таблица 1. Основные объекты синхронизации процессов

Объект

Назначение

Мьютекс

Разрешает взаимно исключающий доступ

Семафор

Разрешает доступ к известному числу нитей

Событие

Разрешает доступ к любому числу ожидающих нитей

Объект синхронизации обладает двумя состояниями: сигнальным и несигнальным. Когда объект синхронизации находится в состоянии занятости, или несигнальном со­стояния, выполнение ожидающей нити не может быть продолжено. А когда объект синхронизации оказывается в сигнальном состоянии, ожидающая нить может продол­жить свое выполнение.

Функции ожидания (wait functions) представляют собой набор вызовов API, которые приостанавливают выполнение нитей до тех пор, пока не станет истинным заданный ряд условий. Функции ожидания проверяют сигнальное состояние объектов синхро­низации. Если указанный объект оказывается в сигнальном состоянии, функция ожи­дания завершается, а выполнение нити продолжается. В противном случае функция ожидания будет поддерживать нить в хорошо оптимизированном цикле, опрашивая состояние объекта синхронизации до тех пор, пока оно не станет сигнальным либо не истечет время ожидания.

Название мъютекса (mutex object) происходит от понятия "взаимное исключение" (mutual exclusion). Мьютекс может одновременно принадлежать только одной нити. Следовательно, если мьютекс принадлежит одной нити, а другая нить запрашивает права владения им, то запрашивающая нить может получить эти права на мьютекс лишь в том случае, когда владеющая им нить уступит свои права. Известный мьютекс Winl6Lock или Winl6Mutex используется в Windows 9.x для защиты нереентрабельного 16-разрядного кода в интерфейсе GDI и USER от опасности одновременного выполнения. В примере, приведенном в описании функции CreateMutex далее в гла­ве, продемонстрировано применение мьютексов.

Семафор (semaphore object) начинает действовать с назначенного для него началь­ного отсчета. Всякий раз когда нить получает права владения этим объектом (через функцию ожидания), счетчик в семафоре уменьшается на единицу. И всякий раз ког­да нить уступает свои права владения этим объектом, счетчик в семафоре увеличива­ется на единицу. Как только счетчик в семафоре достигает нуля, семафор блокиру­ется в несигнальном состоянии и ни одна из нитей не может получить к нему доступ.

Одним из удачных примером применения семафора служит управление распреде­лением конечных ресурсов. Управление запросом каждого ресурса выполняет сема­фор, действие которого автоматически прекращается по достижении запрограммиро­ванного предела. Всякий раз когда запрашивающей нити уже не требуется ресурс, семафор освобождается. Значение счетчика в семафоре всегда сравнимо с количе­ством доступных ресурсов. Семафоры используются в примере, приведенном в опи­сании функции CreateSemaphore далее в главе.

События (event objects) позволяют синхронизировать доступ к ресурсу со стороны любого числа нитей. При этом доступ к ресурсу предоставляется программным путем. Существует два вида событий: события, сбрасываемые вручную, и события, сбрасы­ваемые автоматически.

Сбрасываемое вручную событие (manual-reset event object) устанавливается в сигналь­ное состояние программным путем через вызов функции SetEvent. Событие перехо­дит в несигнальное состояние после обращения к функции ResetEvent. Функция PulseEvent устанавливает и сбрасывает события по очереди. Сбрасываемые вручную события разрешают всем нитям, ожидающим наступления такого события, продол­жить свое выполнение. Сбрасываемые вручную события используются в примере, приведенном в описании функции CreateEvent далее в главе.

Автоматически сбрасываемое событие (auto-reset event object) сбрасывается самосто­ятельно после освобождения одной ожидающей нити. Все остальные нити продолжают ожидать до тех пор, пока данное событие опять не перейдет в несигнальное состоя­ние. Автоматически сбрасываемые события разрешают управляемый последователь­ный доступ к синхронизированному коду нитям разных процессов подобно тому, как объекты критических участков кода разрешают нитям одного и того же процесса пос­ледовательный доступ к коду. Автоматически сбрасываемые события используются в примере, приведенном в описании функции OpenEvent далее в этой главе.

Кроме того, в приложении в качестве объектов синхронизации можно использовать объекты, перечисленные в табл. 2. Они не переходят в несигнальное состояние до тех пор, пока не возникнет заданное условие.

Таблица 2. Другие объекты синхронизации

Объект

Сигнальное условие

Уведомление об изменении

Переходит в сигнальное состояние, когда происходит заданное изменение в структуре файловой системы

Ввод с консоли

Переходит в сигнальное состояние по готовности непрочитанного ввода с консоли

Процесс

Переходит в сигнальное состояние при завершении процесса

Нить

Переходит в сигнальное состояние при завершении нити