|
В операционных системах Windows проблема взаимного исключения для параллельных потоков, выполняемых в контексте одного процесса, решается при помощи объекта типа CRITICAL_SECTION, который не является объектом ядра операционной системы. Для работы с объектами типа CRITICAL_SECTION используются следующие функции:
// инициализация критической секции
VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); // вход в критическую секцию
VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
// попытка войти в критическую секцию
BOOL TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
// выход из критической секции
VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
// разрушение объекта критическая секция
VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
Каждая из этих функций имеет единственный параметр, указатель на объект типа CRIТICAL_SЕСТION. Все ЭТИ функции, за исключением TryEnterCriticalSection, не возвращают значения. Функция TryEnterCriticalSection возвращает ненулевое значение, если поток вошел в критическую секцию или уже находится в ней, в противном случае функция возвращает значение FALSE. Отметим также, ЧТО функция TryEnterCriticalSection поддерживается только операционной системой Windows 2000.
Кратко рассмотрим порядок работы с этими функциями. Для этого предположим, что при проектировании программы мы выделили в параллельных потоках критические секции, в которых используется ресурс, разделяемый этими потоками. Тогда мы определяем в нашей программе объект типа CRITICAL_SECTION и считаем, что имя этого объекта логически связано с используемым разделяемым ресурсом. Перед тем как начать работу с объектом типа CRITICAL_SECTION, его необходимо инициализировать. Для этого и предназначена функция initializeCriticaiSection. После инициализации нашего объекта типа CRITICAL_SECTION мы в каждом из параллельных потоков пред входом в критическую секцию вызываем функцию EnterCritical Section, которая исключает одновременный вход в критические секции, выполняющиеся в параллельных потоках и связанные с нашим разделяемым ресурсом. После завершения работы с разделяемым ресурсом поток должен покинуть свою критическую секцию, что выполняется посредством вызова функции LeaveCriticalSection. После окончания работы с объектом типа CRITICAL_SECTION необходимо освободить все системные ресурсы, которые использовались этим объектом. Для этой цели служит функция DeleteCriticalSection.
|
|
|
В заключение отметим следующее. Так как объекты типа CRITICAL_SECTION не являются объектами ядра операционной системы, то работа с ними происходит несколько быстрее, чем с объектами синхронизации, которые являются объектами ядра операционной системы. Это происходит потому, что обращение к объектам ядра операционной системы требует дополнительной работы на переключение контекстов потоков из режима пользователя в защищенный режим ядра операционной системы. Поэтому при разработке многопоточных приложений для решения задач взаимного исключения, как правило, используют объекты типа CRITICAL_SECTION. |
|