Критические разделы
В многопоточной среде часто возникают проблемы, связанные с использованием параллельно исполняемыми потоками одних и тех же данных или устройств. Например, один из потоков, получает данные извне и помещает их в некоторый буфер памяти компьютера; Другой поток выбирает эти данные из буфера и отображает их на экран. Теперь представьте, что первый поток занес изменил только
– 77 –
половину данных в буфере, операционная система переключилась на выполнение второго потока, и второй поток вывел на экран половину новых и половину старых данных.
В других случаях одновременное обращение к памяти может привести к неправильной работе программ, зависанию программы, потере данных и т.п.
Один из путей устранения конфликта состоит в том, что программист может определить участок потока, который должен быть выполнен без прерывания, т.е. пока участок потока не будет выполнен до конца, никакой из потоков данного процесса не будет выполняться.
Данный участок потока называется критическим разделом. Существует четыре функции работы с критическим разделом. Чтобы их использовать необходимо определеить объект типа критический раздел:
CRITICAL_SECTION cs;
Объект типа критический раздел сначала должен быть инициализирован одним из потоков программы с помощью функции:
InitializeCriticalSection(&cs);
Эта функция создает критический раздел с именем cs. После инициализации объекта "критический раздел" поток входит в критический раздел, вызывая функцию:
EnterCriticalSection(&cs);
В этот момент поток становиться владельцем объекта. Два различных потока не могут быть владельцами одного объекта одновременно. Следовательно, если один поток вошел в критический раздел, то следующий поток, вызывая функцию EnterCriticalSection(&cs); с тем же самым объектом, будет задержан внутри функции. Возврат из функции произойдет только тогда, когда первый поток покинет критический раздел, вызвав функцию:
LeaveCriticalSection(&cs);
В этот момент второй поток, задержанный в функции EnterCriticalSection(&cs) , станет владельцем критического раздела, и его выполнение будет возобновлено.
Когда критический раздел больше не нужен вашей программе, его можно удалить с помощью функции:
DeleteCriticalSection(&cs);
Это приведет к освобождению всех ресурсов системы, задействованных для поддержки объекта критический раздел.
Программа может создавать несколько критических разделов. Существенное ограничение при использовании критических разделов состоит в том, что таким образом можно синхронизировать только потоки одного процесса и нельзя осуществить синхронизацию процессов (действительно, ведь переменная cs объявлена в процессе и не видна из других процессов).
Дата добавления: 2016-11-22; просмотров: 651;