Критическая секция
Критическая секция — участок исполняемого кода программы, в котором производится доступ к общему ресурсу (данным или устройству), который не должен быть одновременно использован более чем одним потоком выполнения. При нахождении в критической секции двух (или более) потоков возникает состояние «гонки» («состязания»). Во избежание данной ситуации необходимо выполнение четырех условий:
- Два потока не должны одновременно находиться в критических областях.
- В программе не должно быть предположений о скорости или количестве процессоров.
- Поток, находящийся вне критической области, не может блокировать другие потоки.
- Невозможна ситуация, в которой поток вечно ждет попадания в критическую область.
Критическая секция (англ. critical section) — объект синхронизации потоков, позволяющий предотвратить одновременное выполнение некоторого набора операций (обычно связанных с доступом к данным) несколькими потоками. Критическая секция выполняет те же задачи, что и мьютекс.
Между мьютексом и критической секцией есть терминологические различия: так процедура, аналогичная «захвату» мьютекса, называется входом в критическую секцию (англ. enter), а аналогичная снятию блокировки мьютекса — выходом из критической секции (англ. leave).
Процедура входа и выхода из критических секций обычно занимает меньшее время, нежели аналогичные операции мьютекса, что связано с отсутствием необходимости обращаться к ядру ОС.
В операционных системах семейства Microsoft Windows разница между мьютексом и критической секцией в том, что мьютекс является объектом ядра и может быть использован несколькими процессами одновременно, критическая секция же принадлежит процессу и служит для синхронизации только его потоков.
Критические секции Windows имеют оптимизацию, заключающуюся в использовании атомарно изменяемой переменной наряду с объектом «событие синхронизации» ядра. Захват критической секции означает атомарное увеличение переменной на 1. Переход к ожиданию на событии ядра осуществляется только в случае, если значение переменной до захвата было уже больше 0, то есть происходит реальное «соревнование» двух или более потоков за ресурс.
Таким образом, при отсутствии соревнования захват/освобождение критической секции обходятся без обращений к ядру.
Кроме того, захват уже занятой критической секции до обращения к ядру какое-то малое время ждёт в цикле (кол-во итераций цикла (англ. spin count) задаётся функциями InitializeCriticalSectionAndSpinCount() или SetCriticalSectionSpinCount()) опроса переменной числа текущих пользователей, и, если эта переменная становится равной 0, то захват происходит без обращений к ядру.
Сходный объект в ядре Windows называется FAST_MUTEX (ExAcquire/ReleaseFastMutex). Он отличается от критической секции отсутствием поддержки рекурсивного повторного захвата тем же потоком.
Аналогичный объект в Linux называется фьютекс.
См. также
Ссылки
- Блудов Павел. Критические секции . rsdn.ru (14 марта 2005). Дата обращения: 18 августа 2010. Архивировано 17 марта 2012 года.
- Fast Mutexes and Guarded Mutexes (англ.). MSDN (6 марта 2010). Дата обращения: 18 августа 2010. Архивировано 17 марта 2012 года.