Критическая секция - это блок кода, при выполнении которого поток не может быть прерван.
Имеется четыре функции для работы с критическими разделами.
Перед тем, как использовать функции для работы с критическими разделами, необходимо определить объект критический раздел, который является глобальной переменной типа CRITICAL_SECTION. Например:
CRITICAL_SECTION cs; // объявление глобальной переменной- Тип данных CRITICAL_SECTION является структурой, но ее поля используются только самой Windows.
Объект критический раздел сначала должен быть инициализирован одним из потоков программы с помощью функции:
InitializeCriticalSection(&cs);- Эта функция создает критический раздел с именем cs. Чаще всего этот объект создается при инициализации процесса, т.е. главным потоком в функции WinMain.
После инициализации объекта критического раздела любой поток может войти в критический раздел, осуществляя вызов:
EnterCriticalSection(&cs);- В этот момент именно этот поток становится владельцем объекта.
Два различных потока не могут быть владельцами одного объекта критический раздел одновременно. Следовательно, если один поток вошел в критический раздел, то следующий поток, вызывая функцию EnterCriticalSection с тем же самым объектом критический раздел, будет задержан внутри функции EnterCriticalSection. Возврат из функции произойдет только тогда, когда первый поток покинет критический раздел, вызвав функцию
LeaveCriticalSection(&cs);- В этот момент второй поток, задержанный в функции EnterCriticalSection, станетвладельцем критического раздела, и его выполнение будет возобновлено.
Обычно вызовы функций EnterCriticalSection и LeaveCriticalSection осуществляют до и после фрагмента кода потока, при выполнении которого могут возникнуть проблемы с разделением данных:
EnterCriticalSection(&cs); // критичекий фрагмент кода потока ................................... LeaveCriticalSection(&cs);Когда объект критический раздел больше не нужен процессу, его можно удалить (обычно в функции WinMain) с помощью функции:
DeleteCriticalSection(&cs);- Это приведет к освобождению всех ресурсов системы, задействованных для поддержки объекта критический раздел.
Механизм критических разделов основан на принципе взаимного исключения (mutual exclusion). Только один поток может быть владельцем критического раздела в каждый конкретный момент времени. Следовательно, один поток может войти в критический раздел, установить значения полей структуры и выйти из критического раздела. Другой поток, использующий эту структуру, также мог бы войти в критический раздел с тем же именем перед осуществлением доступа к полям структуры, а затем выйти из критического раздела.
Следует отметить, что
- Объект критический раздел не может быть программой перемещен или скопирован. Процесс также не должен модифицировать объект, а должен обращаться с ним, как с “черным ящиком”.
- Возможно определение нескольких объектов типа CRITICAL_SECTION. Если в программе есть несколько потоков, то потоки, разделяющие один набор данных, могут использовать первый объект типа CRITICAL_SECTION, другие потоки, разделяющие другие наборы данные, - второй объект, и т.д.
· · Следует очень осторожно использовать использование критического раздела в главном потоке. Если вторичный поток проводит слишком много времени в его собственном критическом разделе, то это может привести к “зависанию” главного потока на слишком большой период времени.
- Существует одно ограничение в использовании критических разделов. Оно заключается в том, что их можно применять для синхронизации потоков только в рамках одного процесса.
Но
Бывают случаи, когда необходимо синхронизировать действия потоков различных процессов, которые разделяют какие-либо ресурсы (например, память). Использовать критические разделы в такой ситуации нельзя. Вместо них используются мьютексы (mutex object).
Приведем еще одно средство для координации и синхронизации действий потоков - семафоры. Семафоры можно использовать для ограничения количества параллельных доступов к разделяемому ресурсу. При создании семафора указывается это максимальное количество. Каждый раз, когда поток, ожидавший семафор, занимает ресурс, счетчик семафора уменьшается на единицу. При освобождении семафора этот счетчик вновь увеличивается на единицу.
Дата добавления: 2017-01-26; просмотров: 1432;