![]() |
Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | |
|
Критические секции являются наиболее простым средством синхронизации задач для обеспечения последовательного доступа к ресурсам. Они работают быстро, не снижая заметно производительность системы, но обладают одним существенным недостатком - их можно использовать только для синхронизации задач в рамках одного процесса. В отличие от критических секций объекты Mutex, которые мы рассмотрим немного позже, допускают синхронизацию задач, созданных разными процессами.
Критическая секция создается как структура:
CRITICAL_SECTION csWindowPaint;
Обычно эта структура располагается в области глобальных переменных, доступной всем запущенным задачам процесса. Так как каждый процесс работает в своем собственном адресном пространстве, вы не сможете передать адрес критической секции из одного процесса в другой. Именно поэтому критические секции нельзя использовать для синхронизации задач, созданных разными процессами.
Инициализация критической секции
Перед использованием критической секции ее необходимо проинициализировать, вызвав для этого функцию InitializeCriticalSection:
CRITICAL_SECTION csWindowPaint;
InitializeCriticalSection(&csWindowPaint);
Функция InitializeCriticalSection имеет только один параметр (адрес структуры типа CRITICAL_SECTION) и не возвращает никакого значения.
Удаление критической секции
Если критическая секция больше не нужна, ее нужно удалить при помощи функции DeleteCriticalSection, как это показано ниже:
DeleteCriticalSection(&csWindowPaint);
При этом освобождаются все ресурсы, созданные операционной системой для критической секции.
Вход в критическую секцию и выход из нее
Две основные операции, выполняемые задачами над критическими секциями, это вход в критическую секцию и выход из критической секции. Первая операция выполняется при помощи функции EnterCriticalSection, вторая - при помощи функции LeaveCriticalSection. Эти функции, не возвращающие никакого значения, всегда используются в паре, как это показано в следующем фрагменте:
EnterCriticalSection(&csWindowPaint);
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
DrawText(hdc, "SDI Window", -1, &rc,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
LeaveCriticalSection(&csWindowPaint);
В качестве единственного параметра функциям EnterCriticalSection и LeaveCriticalSection необходимо передать адрес стрктуры типа CRITICAL_SECTION, проинициализированной предварительно функцией InitializeCriticalSection.
Как работают критические секции?
Если одна задача вошла в критическую секцию, но еще не вышла ее, то при попытке других задач войти в ту же самую критическую секцию они будут переведены в состояние ожидания. Задачи пробудут в этом состоянии до тех пор, пока задача, которая вошла в критическую секцию, не выйдет из нее.
Таким образом гарантируется, что фрагмент кода, заключенный между вызовами функций EnterCriticalSection и LeaveCriticalSection, будет выполняться задачами последовательно, если все они работают с одной и той же критической секцией.
Дата публикования: 2015-10-09; Прочитано: 240 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!