Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 6004.doc
Скачиваний:
21
Добавлен:
30.04.2022
Размер:
1.29 Mб
Скачать

3.2.6. Синхронизация задач

Синхронизация заключается в том, что некоторые задачи должны приостанавливать свое выполнение до тех пор, пока не наступит событие, связанное с другими задачами. Использование значений глобальных переменных в качестве признаков наступления событий не может считаться хорошим решением, т.к. проверяющая в цикле значение некоторой переменной задача полностью использует свои кванты времени, что отрицательно влияет на производительность системы. Приемлемым решением можно считать сообщение планировщику о том, что задача находится в состоянии ожидания и перевод задачи в состояние приостановки. При наступлении ожидаемого события задача возобновляется и использует свои кванты времени.

3.2.6.1Ожидание завершения задачи или процесса

Каждому процессу или задаче в системе соответствует идентификатор. Если задача выполняется, то идентификатор находится в так называемом неотмеченном состоянии (nonsigned). Как только задача или процесс завершится, он переходит в отмеченное состояние (signed). Для того, чтобы отследить это изменение состояния иден- тификатора используют функцию:

DWORD WaitForSingleObject (НANDLE НObject,

DWORD dwTimeOut);

Первым параметром передается идентификатор объекта, вторым - время таймаута, в течении которого следует ждать изменения состояния идентификатора. Если передать dwTimeOut = INFINITE, то время ожидания будет бессрочным. В качестве идентификатора можно передавать идентификаторы задач, процессов, событий, файлов и других объектов.

Функция возвращает

WAIT_FAILED при ошибке;

WAIT_OBJECT_0 при достижении отмеченного состояния;

WAIT_TIMEOUT при истечении таймаута;

WAIT_ABANDONED при принудительном завершении ожидания.

Ожидание завершения нескольких задач или процессов

DWORD WaitForMuitipleObject (DWORD cObject,

НANDLE*1pНObject,

BOOL fWaitAll,

DWORD dwTimeOut);

Первый параметр - это количество элементов массива идентификаторов. Второй параметр содержит указатель на массив идентификаторов. Третий параметр - тип ожидания. Если параметр установлен в значение True, то ожидание завершается при завершении всех задач, т.е. когда все идентификаторы переведены в состояние signed. Если установлено значение False, то функция завершается при переключении хотя бы одного идентификатора в отмеченное состояние. Коды завершения этой функции практически те же, за исключением нормального и принудительного завершения. При нормальном завершении функция возвращает результат в диапазоне от WAIT_OBJECT_0 до (WAIT_OBJECT_0+cObject-1), которое в зависимости от значения параметра fWaitAll означает, что либо все идентификаторы перешли в отмеченное состояние, либо за вычетом WAIT_OBJECT_0 равно индексу идентификатора отмеченного объекта. Аналогично код принудительного завершения возвращается в диапазоне от WAIT_ABANDONED_0 до (WAIT_ABANDONED_0+cObject-1).

3.2.6.2Синхронизация с помощью событий

Событие - это объект, который характеризуется одним свойством - фактом своего наступления. Событие может наступить, а может и не наступить. Наступление события характеризуется переводом его идентификатора в отмеченное состояние. Любое событие, которое существует в системе, должно быть создано. Создание события выполняет функция:

НANDLE CreateEvent (LPSECURITY_ATTRIBUTES lpEventAttr,

BOOL bManualReset,

BOOL bInitialState,

LPCTSTR lpName);

Первый параметр содержит указатель на структуру с атрибутами системы защиты. Параметр bManualReset - флаг ручного сброса события. Значение True сообщает о том, что сброс может быть выполнен только с помощью функции ResetEvent, а значение False обеспечивает автоматический сброс события сразу после того, как задача завершит ожидание этого события; Третий параметр - флаг начального состояния: True - событие отмечено, False - не отмечено; Последний параметр может передавать указатель на символьную строку, содержащую имя события. Имя события задается, когда предполагается синхронизировать несколько самостоятельных процессов. Если предполагается использовать синхронизацию в рамках одного процесса, то lpName указывается NULL.

Событие создается только в одном процессе. В этой же задаче событие автоматически открывается. Для всех других процессов, которые будут использовать это событие, необходимо открыть идентификатор события:

НANDLE OpenEvent (DWORD fdwAccess,

BOOL bInНerit,

LPCTSTR lpName);

Первыми передаются флаги доступа, возможные значения которых EVENT_ALL_ACCESS - все флаги; EVENT_MODIFY_STATE - позволяет переводить идентификатор в отмеченное или неотмеченное состояние; SYNCНRONIZE- идентификатор можно использовать в файлах, ожидающих событий.

Второй параметр - флаг наследования: True - идентификатор может наследоваться потомком, False - идентификатор не может наследоваться потомком.

Третий параметр - символьная строка с именем события.

Установка события (перевод в отмеченное состояние):

BOOL SetEvent (HANDLE НEvent);

Сброс события в неотмеченное состояние

BOOL ResetEvent (HANDLE НEvent);

Функция пульсирующей установки с последующим сбросом:

BOOL PulseEvent (HANDLE НEvent);

Если эта функция вызвана для события, работающего в ручном режиме, то все задачи, ожидающие этого события, завершат ожидание и продолжат работу. Событие при этом сбрасывается в неотмеченное состояние. В автоматическом режиме функция возвращает управление, как только хотя бы одна задача, ожидающая это событие, перейдет в активное состояние.