Критические секции
Еще одним средством синхронизации потоков служат переменные типа CRITICAL_SECTION. По назначению они совпадают с рассмотренными выше мьютексами, однако реализация двоичного семафора в этом случае совершенно иная. Если мьютексы – это один из типов объектов ядра, то критические секции – просто переменные. В чем здесь принципиальная разница? В том, что объекты существуют в памяти системы, поэтому прикладная программа не может напрямую обратиться к объекту, прочитать или записать его значение. Программа может только получить хэндл объекта, а затем она поручает системе выполнить то или иное действие с объектом, на который указывает данный хэндл. Такое решение позволяет использовать один объект для связи нескольких процессов, сохраняя при этом изоляцию памяти процесса от памяти системы и других процессов.
Недостаток использования объектов ядра в том, что обращение к ним всякий раз требует переключения контекста с пользовательского на системный и обратно, а это требует времени. Такова цена изоляции процессов.
Если требуется синхронизировать работу нитей одного и того же процесса, то более «дешевым» решением может быть использование переменных CRITICAL_SECTION. Программист должен описать переменную этого типа в программе процесса, при этом для всех нитей процесса будет доступен адрес этой переменной. Перед началом работы с критической секцией одна из нитей процесса должна вызвать функцию InitializeCriticalSection, передав ей адрес переменной. Затем он может использовать функцию EnterCriticalSection, чтобы занять двоичный семафор, и функцию LeaveCriticalSection, чтобы освободить его. Как и для мьютекса, один и тот же поток может несколько раз занять критическую секцию, но потом должен столько же раз освободить ее. Имеется еще удобная функция TryEnterCriticalSection, которая позволяет избежать блокировки и занимает критическую секцию, только если та была свободна в момент обращения. По истечении необходимости в синхронизации нитей следует вызвать функцию DeleteCriticalSection.
Вызов всех перечисленных функций выполняется системой гораздо быстрее, чем вызов функций, работающих с хэндлами объектов, поскольку вся работа выполняется в памяти вызывающего процесса, без переключения контекста памяти. Но зато невозможно использовать критические секции для синхронизации нитей разных потоков, для этого нужны мьютексы.
Дата добавления: 2015-09-07; просмотров: 506;