19. Синхронизация потоков в пределах одного процесса. Критические секции. Спин-блокировки. Interlocked-функции.
Примитив синхронизации — это объект, который помогает управлять многопоточным приложением. В Windows 2000 доступны следующие основные типы примитивов синхронизации:
атомарные операции API-уровня;
критические секции;
Критическая секция (critical section) — это небольшой участок кода, который должен использоваться только одним потоком одновременно. Если в одно время несколько потоков попытаются получить доступ к критическому участку, то контроль над ним будет предоставлен только одному из потоков, а все остальные будут переведены в состояние ожидания до тех пор, пока участок не освободится. Для использования критической секции необходимо определить переменную типа CRITICAL_SECTION:
CRITICAL_SECTION cs;
Поскольку эта переменная должна находиться в области видимости для каждого использующего ее потока, обычно она объявляется как глобальная. Эту переменную следует инициализировать до ее первого применения с помощью функции InitializeCriticalSection(&cs); Чтобы завладеть критическим участком, поток должен вызвать функцию EnterCriticalSection(&cs);
Если критический участок не используется в данный момент другим потоком, он обозначается системой как занятый, и поток немедленно продолжает выполнение. Если критический участок уже используется, то поток блокируется до тех пор, пока участок не будет освобожден. После вызова EnterCriticalSection следуют инструкции, принадлежащие критическому участку.
Конец критического участка обозначается вызовом функции LeaveCriticalSection(&cs);
Как только поток получает контроль над критическим участком, доступ других потоков к этому участку блокируется. При этом очень важно, чтобы время выполнения критического участка было минимальным. Это позволит добиться наилучших результатов работы приложения. Если критический участок больше не нужен, используемые им ресурсы освобождаются вызовом функции DeleteCriticalSection.
Спин-блокировки представляют собой чрезвычайно низкоуровневое средство синхронизации, предназначенное в первую очередь для применения в многопроцессорной конфигурации с разделяемой памятью. Они обычно реализуются как атомарно устанавливаемое булево значение (истина – блокировка установлена). Аппаратура поддерживает подобные блокировки командами вида "проверить и установить".
При попытке установить спин-блокировку, если она захвачена кем-то другим, как правило, применяется активное ожидание освобождения, с постоянным опросом в цикле состояния блокировки. Естественно, при этом занимается процессор, так что спин-блокировки следует устанавливать только на очень короткое время и их владелец не должен приостанавливать свое выполнение.
Большая часть синхронизации потоков связана с атомарным доступом (atomic access) — монопольным захватом ресурса обращающимся к нему потоком. Win32 API предоставляет несколько функций для реализации взаимно блокированных операций. Все Interlocked-функций работают корректно только при условии, что их аргументы выровнены по границе двойного слова (DWORD).
Функция Interlockedlncrement, имеющая прототип LONG InterlockedIncrement(LPLONG lpAddend); инкрементирует 32-разрядную переменную, адрес которой задается параметром LpAddend. Функция возвращает новое значение указанной переменной.
Функция Interlocked Decrement определена аналогично функции Interlockedlncrement, но она декрементирует 32-разрядную переменную. Пара функций
LONG InterlockedExchange(LPLONG IpTarget. LONG Value):
PVOID InterlockedExchangePointer(PVOID* ppvTarget. PVOID pvValue):
монопольно заменяет текущее значение переменной типа LONG, адрес которой передается в первом параметре, значением, передаваемым во втором параметре. В 32-разрядном приложении обе функции работают с 32-разрядными значениями. В 64-разрядной программе первая функция оперирует 32-разрядными значениями, а вторая — 64-разрядными. Обе функции возвращают исходное значение переменной.
Следующая функция добавляет к значению переменной, адрес которой передается в первом параметре, значение, передаваемое во втором параметре:
LONG InterlockedExchangeAdd(LPLONG IpAddend. LONG Increment):
Еще две функции выполняют операцию сравнения и присваивания по результату сравнения:
LONG InterlockedCompareExchangetLPLONG IpDestination, LONG Exchange, LONG Comparand);
PVOID InterlockedCompareExchangePointer(PVOID* ppvDestination, PVOID pvExchange, PVOID pvComparand);
Если значение переменной, адрес которой передается в первом параметре, совпадает со значением, передаваемым в третьем параметре, то оно заменяется значением, передаваемым во втором параметре. В 32-разрядном приложении обе функции работают с 32-разрядными значениями. В 64-разрядной программе первая функция оперирует 32-разрядными значениями, а вторая — 64-разрядными. Обе функции возвращают исходное значение переменной, заданной первым параметром.
Работая с критическими секциями или применяя Interlocked-функции, программа не переключается в режим ядра. Поэтому эти виды синхронизации называют синхронизацией в пользовательском режиме. Она отличается высокой скоростью реализации. Главным недостатком такой синхронизации является невозможность ее применения для потоков, принадлежащих разным процессам.
Yandex.RTB R-A-252273-3
- Модель программного интерфейса ос windows. Понятие объекта ядра и описателя объекта ядра операционной системы Windows. Нотация программного интерфейса.
- Понятие пользовательского режима и режима ядра операционной системы Windows. Модель виртуальной памяти процесса в пользовательском режиме и в режиме ядра операционной системы Windows.
- Обзор архитектуры и основных модулей операционной системы Windows.
- Системный реестр операционной системы Windows.
- 5. Основные элементы программ с оконным пользовательским интерфейсом. Минимальная программа для ос Windows с окном на экране. Создание и отображение окна.
- Понятие оконного сообщения. Источники сообщений. Очередь сообщений. Цикл приема и обработки сообщений. Процедура обработки сообщений.
- 8. Вывод информации в окно. Механизм перерисовки окна.
- 9. Принципы построения графической подсистемы ос Windows. Понятие контекста устройства. Вывод графической информации на физическое устройство.
- 10. Рисование геометрических фигур. Графические инструменты. Управление цветом. Палитры цветов.
- 11. Растровые изображения. Вывод растровых изображений. Значки и курсоры. Вывод растровых изображений с эффектом прозрачного фона.
- 12. Вывод текста. Логические и физические шрифты.
- 13. Системы координат. Трансформации. Режимы масштабирования.
- 14. Понятие ресурсов программ. Виды ресурсов. Работа с ресурсами. Меню. Окна диалога.
- 15. Понятие динамически подключаемой библиотеки. Структура dll-библиотеки. Создание dll-библиотеки. Использование dll-библиотеки в программе. Статический и динамический импорт.
- 16. Отображение файлов в память.
- 17. Организация многозадачности в операционной системе Windows. Понятие процесса и потока. Контекст потока. Создание и завершение процессов и потоков.
- 18. Механизм приоритетов в операционной системе Windows. Класс приоритета процесса. Относительный приоритет потока. Базовый и динамический приоритеты потока.
- 19. Синхронизация потоков в пределах одного процесса. Критические секции. Спин-блокировки. Interlocked-функции.
- 20. Синхронизация потоков разных процессов. Объекты синхронизации: флаги, семафоры, события, ожидаемые таймеры, именованные и неименованные «трубы» (каналы).
- 21. Синхронизация потоков при создании общих данных с помощью двойных проверок (double-checked locking).
- 22. Синхронизация потоков с помощью мониторов Хоара.
- 24. Структуры данных общего назначения в режиме ядра. Представление строк стандарта Unicode. Представление двусвязных списков.
- 25. Понятие прерывания, исключения и системного вызова.
- 26. Аппаратные и программные прерывания. Таблица обработчиков прерываний. Понятие процедуры обработки прерываний (isr).
- 27. Программируемый контролер прерываний. Уровни прерываний. Механизм вызова прерываний. Функция KeBugCheckEx.
- 28. Исключения. Механизм обработки исключения.
- 29. Системные вызовы. Выполнение системного вызова.
- 30. Понятие отложенной процедуры (dpc). Назначение отложенных процедур.
- 31. Понятие асинхронной процедуры (apc). Назначение асинхронных процедур. Асинхронные процедуры режима ядра и пользовательского режима.
- 32. Понятие рабочего элемента ядра (Work Item). Назначение рабочих элементов.
- 33. Пулы памяти. Пул подкачиваемой памяти, пул неподкачиваемой памяти, пул сессии, особый пул. Тегирование пулов. Структура данных пула.
- 34. Оптимизация использования оперативной памяти с помощью списков предыстории (look-aside lists).
- 35. Блокирование страниц в памяти. Списки описателей памяти (mdl) и их использование
- 36. Представление объекта ядра в памяти. Менеджер объектов.
- 37. Структура драйвера операционной системы Windows. Точки входа в драйвер.
- 38. Объект, описывающий драйвер. Объект, описывающий устройство. Объект, описывающий файл. Взаимосвязь объектов.
- 39. Запрос ввода-вывода (irp). Схема выполнения ввода-вывода в стеке драйверов.
- 40. Структура api ядра ос Windows: Kernel api, Windowing api, Messaging api. Функции ZwXxx/NtXxx в пользовательском режиме и в режиме ядра.
- 42. Перехват функций ос Windows api в пользовательском режиме. Интерфейсный модуль ntdll.Dll.
- 43. Перехват вызова функций ос Windows в режиме ядра. Встроенная защита от перехвата в новейших версиях ос Windows.