Объекты критической секции (critical section) обеспечивают синхронизацию подобно той, как это делается при помощи объектов типа мьютекс, за исключением того, что объекты критической секции могут использоваться только потоками единственного процесса. Объекты событие, мьютекс и семафор могут также использоваться и в однопроцессном приложении, но объекты критической секции предоставляют немного более быстрый, более эффективный механизм для синхронизации взаимоблокировки (специальная для процессора проверка и набор команд). Подобно объекту типа мьютекс, объект критической секции может принадлежать одновременно только одному потоку, что делает его полезным чтобы предохранить совместно используемый ресурс от одновременного доступа. Нет какого-либо гарантированного порядка в котором потоки получают монопольное использование критической секции, однако, система должен быть справедливой ко всем потокам. В отличие от объекта типа мьютекс, там не способа сообщить, была ли критическая секция оставлена.
Процесс несет ответственность распределение памяти, используемой критической секцией. Как правило, это происходит просто при помощи объявления переменной типа CRITICAL_SECTION. Прежде, чем потоки процесса смогут использовать ее, надо инициализировать критическую секцию, используя функцию InitializeCriticalSection или InitializeCriticalSectionAndSpinCount.
Поток использует функцию EnterCriticalSection или TryEnterCriticalSection, чтобы запросить монопольное использование критической секции. Он использует функцию LeaveCriticalSection, чтобы освободить монопольное использование критической секции. Если объект критической секции в текущий момент принадлежит другому потоку, функция EnterCriticalSection ждет неограниченно монопольное использование. Напротив, когда объект типа мьютекс используется для взаимоблокировки, функции ожидания принимают заданный интервал времени простоя. Функция TryEnterCriticalSection пытается входить в критическую секцию, не блокируя вызывающий поток.
Как только поток овладеет критической секцией, он может сделать дополнительные вызовы функции EnterCriticalSection или TryEnterCriticalSection, не блокируя исполнение своего кода. Это предохраняет поток от самоблокировки в то время, когда ожидает критическую секцию, которой он уже владеет. Чтобы освободить себя от монопольного использования, поток должен вызвать LeaveCriticalSection по разу для каждого случая, когда он входил в критическую секцию.
Поток использует функцию InitializeCriticalSectionAndSpinCount или SetCriticalSectionSpinCount, чтобы установить счет состояния занятости для объекта критической секции. На одно-процессорных системах, счет состояния занятости игнорируется, а счет состояния занятости критической секции устанавливается в 0. На многопроцессорных системах, если критическая секция недоступна, вызывающий поток будет тянуть dwSpinCount время перед выполнением операции ожидания на семафоре, связанном с критической секцией. Если критическая секция становится свободной, в ходе операции протягивания времени, вызывающий поток отменяет операцию ожидания.
Любой поток процесса может использовать функцию DeleteCriticalSection, чтобы освободить системные ресурсы, которые были распределены, когда объект критической секции был инициализирован. После того, как эта функция вызвалась, объект критической секции больше не может использоваться для синхронизации.
Когда объект критической секции находится в монопольном использовании, затрагиваются только другие потоки - это те, которые ожидают монопольного использования при вызове функции EnterCriticalSection. Потоки, которые не ожидают, особождаются, чтобы продолжить выполнение программы.
Назад в оглавление темы |
На главную страницу темы |