На этом шаге мы рассмотрим. синтаксис нескольких функций, используемых для этих целей.
Функции синхронизации делятся на две основные категории - функции ожидания единственного объекта и функции ожидания одного из нескольких объектов.
Функции ожидания единственного объекта
Простейшей функцией ожидания является функция WaitForSingleObject:
function WaitForSingieObject( hHandle: THandle; // идентификатор объекта dwMil1iseconds: DWORD // период ожидания ): DWORD; stdcall;
Эта функция ожидает перехода объекта hHandle в сигнальное состояние в течение dwMilliseconds миллисекунд. Если в качестве параметра dwMilliseconds передать значение INFINITE,
функция будет ждать в течение неограниченного времени. Если параметр dwMilliseconds равен 0, то функция проверяет состояние объекта и немедленно возвращает управление.
Функция возвращает одно из следующих значений:
- WAIT_ABANDONED - поток, владевший объектом, завершился, не переведя объект в сигнальное состояние;
- WAIT_OBJECT_0 - объект перешел в сигнальное состояние;
- WAIT_TIMEOUT - истек срок ожидания (обычно в этом случае генерируется ошибка либо функция вызывается в цикле до получения другого результата);
- WAIT_FAILED - произошла ошибка, например неверное значение hHandle (более подробную информацию можно получить, вызвав функцию GetLastError).
Следующий фрагмент кода запрещает действие Action1 до перехода объекта ObjectHandle в сигнальное состояние. Например, таким образом можно дожидаться завершения процесса, передав в качестве
параметра ObjectHandle его идентификатор, полученный функцией CreateProcess.
var Reason: DWORD; ErrorCode: DWORD; Action1.Enabled := False; try repeat Application.ProcessMessages; Reason := WailForSingleObject(ObjectHandle, INFINITE); if Reason = WAIT_FAILED then begin ErrorCode := GetLastError; raise Exception.CreateFmt( 'Wait for object failed with error: %d', [ErrorCode]); end; until Reason <> WAIT_TIMEOUT; finally Actionl.Enabled := True; end;
В случае когда требуется одновременно с ожиданием объекта перевести в начальное состояние другой объект, может использоваться следующая функция:
function SignalObjectAndWait( hObjectToSignal; THandle; // объект, который будет переведен в сигнальное состояние hObjectToWaitOn: THandle; // объект, который ожидает функция dwMilliseconds: DWORD; // период ожидания bAlertable: BOOL // параметр определяет, должна ли функция возвращать управление // в случае запроса на завершение операции ввода-вывода ): DWORD; stdcall;
Возвращаемые значения аналогичны соответствующим значениям фуyнкции WaitForSingleObject.
Внимание.
В модуле Windows.pas эта функция ошибочно объявлена как возвращающая значеиие типа BOOL. Если вы намерены се использовать, объявите
ее корректно или выполните приведение возвращенного значения к типу DWORD.
Объект hObjectToSignal может быть семафором, событием или мьютексом). Параметр bAlertable определяет, будет ли прерываться ожидание
объекта в случае, если операционная система запросит у потока окончание операции асинхронного ввода-вывода, или асинхронного вызова процедуры.
Более подробно это обсуждается в следующих шагах.
На следующем шаге мы рассмотрим функции ожидания нескольких объектов.