Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Desktop / For_exams / Smirnov / 1 - копия (28)

.txt
Скачиваний:
60
Добавлен:
27.03.2015
Размер:
7.13 Кб
Скачать
29. Программная синхронизация
Синхронизация
Процессы также могут использовать разные типы объектов синхронизации. Точно
так же, как Windows Vista предоставляет множество механизмов для
межпроцессного обмена, она представляет также и множество механизмов синхронизации
(включая семафоры, мьютексы, критические области и события). Все эти меха-
992 Глава 11. Изучение конкретных примеров: Windows Vista
низмы работают с потоками (а не процессами), так что когда поток блокируется
на семафоре, то другие потоки этого процесса (если они есть) могут продолжать
выполнение.
Семафор создается при помощи функции CreateSemaphore интерфейса Win32
API, которая может инициализировать его заданным значением, а также задать
максимальное значение. Семафоры — это объекты режима ядра и поэтому они
имеют дескрипторы безопасности и описатели. Описатель для семафора может
быть сдублирован при помощи DuplicateHandle и передан в другой процесс (чтобы
по одному и тому же семафору могли синхронизироваться несколько процессов).
Семафору можно дать имя в пространстве имен Win32, он может иметь ACL для
своей защиты. Иногда совместное использование семафора по имени более удобно,
чем дублирование описателя.
Имеются вызовы для операций up и down, хотя названия у них несколько
странные: ReleaseSemaphore (это up) и WaitForSingleObject (это down). Можно также
задать тайм-аут для WaitForSingleObject, чтобы вызывающий поток в итоге мог быть
освобожден, даже если семафор останется на значении 0 (однако таймеры создают
условия гонки). WaitForSingleObject и WaitForMultipleObjects — это интерфейсы
для ожидания объектов диспетчеризации (обсуждались в разделе «Структура
системы»). Несмотря на то что в принципе возможно заключить однообъектную
версию этих API в оболочку с более дружественным для семафоров названием,
многие потоки используют многообъектную версию, которая может повлечь за
собой ожидание различных объектов синхронизации и прочих событий (вроде
завершения процессов и потоков, завершения ввода-вывода, поступления сообщений
в сокеты или порты).
Мьютексы — это тоже объекты режима ядра, используемые для синхронизации,
но они проще семафоров (поскольку не имеют счетчиков). По существу это
блокировки, имеющие функции API для блокирования {WaitForSingleObject) и
разблокирования (ReleaseMutex). Подобно описателям семафоров, описатели мьютексов
могут дублироваться и передаваться между процессами, чтобы потоки в разных
процессах могли получить доступ к одному и тому же мьютексу
Третий механизм синхронизации называется «критическая секция» (critical
section). Он реализует концепцию «критических областей». В Windows он похож
на мьютекс, за исключением того, что он является локальным для адресного
пространства создающего потока. Поскольку критические секции не являются
объектами режима ядра, они не имеют явных описателей или дескрипторов безопасности
и не могут передаваться между процессами. Блокирование и разблокирование
выполняется соответственно вызовами EnterCriticalSection и LeaveCriticalSection.
Поскольку эти функции API выполняются первоначально в пространстве
пользователя и делают вызовы ядра только при необходимости в блокировке, то они гораздо
быстрее мьютексов. Критические секции оптимизированы для комбинированного
использования спин-блокировок (на многопроцессорных системах) и
синхронизации ядра (при необходимости). Во многих приложениях большинство критических
секций так редко становятся объектом соперничества или имеют такое краткое
время удерживания, что необходимость в выделении объекта синхронизации ядра
никогда не возникает. Это приводит к очень существенной экономии памяти ядра.
11.4. Процессы и потоки в Windows Vista 993
Последний из обсуждаемых механизмов синхронизации использует объекты
режима ядра, которые называются событиями (events). Как мы уже описывали
ранее, существует два их вида: события уведомления (notification events) и
события синхронизации (synchronization events). Событие может быть в одном
из двух состояний: сигнализированном или несигнализированном. Поток может
ждать сигнализации события при помощи WaitForSingleObject. Если другой поток
сигнализирует событие при помощи SetEvent, то результат зависит от типа события.
Для события уведомления — будут освобождены все ждущие потоки, а событие
останется установленным до тех пор, пока не будет сброшено вручную при
помощи ResetEvent. Для события синхронизации — если ждет один или несколько
потоков, то освобождается только один поток и событие сбрасывается.
Альтернативная операция — PulseEvent, которая похожа на SetEvent (за исключением того,
что если никто не ждет, то импульс теряется и событие сбрасывается). В отличие
от нее SetEvent (когда оно происходит в отсутствие ожидающих потоков)
запоминается — событие остается в сигнализированном состоянии, так что следующий
поток (который вызывает API для ожидания события) фактически ждать не будет.
Количество вызовов Win32 API для работы с процессами, потоками и
волокнами составляет почти 100 штук, причем большое их количество в той или иной
форме работает с IPC. Сводка по обсуждавшимся выше вызовам (а также
некоторым другим важным вызовам) дана в табл. 11.14.
Таблица 11.14. Некоторые из вызовов Win32 для управления процессами,
потоками и волокнами
Функция Win32 API Описание
CreateProcess Создать новый процесс
CreateThread Создать новый поток в существующем процессе
CreateFiber Создать новое волокно
ExitProcess Завершить текущий процесс и все его потоки
ExitThread Завершить этот поток
ExitFiber Завершить это волокно
SwitchToFiber Выполнить другое волокно в текущем потоке
SetPriorityClass Установить класс приоритета для процесса
SetTh read Priority Установить приоритет для одного потока
CreateSemaphore Создать новый семафор
CreateMutex Создать новый мьютекс
OpenSemaphore Открыть существующий семафор
OpenMutex Открыть существующий мьютекс
WaitForSingleObject Блокировать по одному семафору, мьютексу и т. д.
WaitForMultipleObjects Блокировать по набору объектов, описатели которых заданы
PulseEvent Установить событие сначала в сигнализированное, а затем в несигна-
лизированное состояние
ReleaseMutex Освободить мьютекс, чтобы другой поток мог завладеть им
ReleaseSemaphore Увеличить счетчик семафора на 1
EnterCriticalSection Установить блокировку на критической секции
LeaveCriticalSection Снять блокировку с критической секции
994 Глава 11. Изучение конкретных примеров: Windows Vista
Обратите внимание, что некоторые из этих вызовов — это не просто системные
вызовы. Некоторые из них являются оболочками, другие содержат значительное
количество библиотечного кода, который отображает семантику Win32 на
собственные вызовы интерфейса NT API. Третьи (относящиеся к интерфейсу волокон)
являются исключительно функциями пользовательского режима, поскольку (как мы
уже упоминали ранее) режим ядра в Windows Vista ничего не знает о волокнах.
Они полностью реализованы средствами библиотек пользовательского режима.
Соседние файлы в папке Smirnov