Книга: Системное программирование в среде Windows
Использование объектов CRITICAL_SECTION для защиты разделяемыхпеременных
Использование объектов CRITICAL_SECTION для защиты разделяемыхпеременных
Использование объектов CRITICAL_SECTION не вызывает сложностей, и одним из наиболее распространенных способов их применения является обеспечение доступа потоков к разделяемым глобальным переменным. Рассмотрим, например, многопоточный сервер (аналогичный представленному на рис. 7.1), в котором необходимо вести учет следующих статистических данных:
• Общее количество полученных запросов.
• Общее количество отправленных ответов.
• Количество запросов, обрабатываемых в настоящее время всеми потоками сервера.
Поскольку переменные счетчиков являются глобальными переменными процесса, нельзя допустить того, чтобы одновременно два потока изменяли их значения. Один из методов обеспечения этого, базирующийся на применении объектов CRITICAL_SECTION, иллюстрирует схема, показанная ниже на рис. 8.2. Использование объектов CRITICAL_SECTION демонстрируется на примере программы 8.1, представляющей намного более простую систему, чем серверная.
Объекты CS могут привлекаться для решения задач, аналогичных той, которую иллюстрирует рис. 8.1, где два потока увеличивают значение одной и той же переменной. Приведенный ниже фрагмент кода обеспечивает нечто большее, нежели простое увеличение переменной, поскольку для этого достаточно было бы воспользоваться функциями взаимоблокировки. Обратите внимание на спецификатор volatile, предотвращающий размещение текущего значения переменной оптимизирующим компилятором в регистре, а не в ячейке памяти, отведенной для хранения переменной. Кроме того, в этом примере используется промежуточная переменная; этот необязательный элемент снижает эффективность программы, однако позволяет более отчетливо продемонстрировать, каким образом решается задача, иллюстрируемая рис. 8.1.
CRITICAL_SECTION cs1;
volatile DWORD N = 0, М;
/* N — глобальная переменная, разделяемая всеми потоками. */
InitializeCriticalSection (&cs1);
…
EnterCriticalSection (&cs1);
if (N < N_MAX) { M = N; M += 1; N = M; }
LeaveCriticalSection (&cs1);
…
DeleteCriticalSection (&cs1);
На рис. 8.2 представлена одна из возможных последовательностей выполнения программы для случая, изображенного на рис. 8.1, и продемонстрировано, каким образом объекты CS упрощают решение проблемы синхронизации.
Программа 8.1 демонстрирует, насколько полезными могут быть объекты CS.
- Необходимость в синхронизации потоков
- Объекты синхронизации потоков
- Объекты критических участковкода
- Использование объектов CRITICAL_SECTION для защиты разделяемыхпеременных
- Пример: простая система "производитель/потребитель"
- Мьютексы
- Семафоры
- События
- Пример: система "производитель/потребитель"
- Обзор: объекты синхронизации Windows
- Дополнительные рекомендации относительно использования мьютексов и объектов CRITICAL_SECTION
- Другие функции взаимоблокировки
- Учет факторов производительности при организации управленияпамятью
- Резюме
- Упражнения
- Восстановление с использованием инструмента gbak
- Особенности системы защиты данных в InterBase
- Типы страниц и их использование
- Иерархия объектов в InterBase
- Использование констант
- Использование переменной окружения ISC_PATH
- Использование сервера Yaffil внутри процесса
- Использование CAST() с типами дата
- Имена объектов длиной 68 символов
- Создание объектов Collection
- Использование типов содержимого и столбцов
- Вызов хранимых процедур InterBase с использованием стандартного синтаксиса ODBC