Программирование для Windows NT

       

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


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

Прототип функции WaitForSingleObject представлен ниже:

DWORD WaitForSingleObject(

  HANDLE hObject,    // идентификатор объекта

  DWORD  dwTimeout); // время ожидания в миллисекундах

В качестве параметра hObject этой функции нужно передать идентификатор объекта, для которого выполняется ожидание, а в качестве параметра dwTimeout - время ожидания в миллисекундах (ожидание может быть и бесконечным, если для времени указать значение INFINITE).

Многие объекты операционной системы Microsoft Windows NT, такие, например, как идентификаторы задач, процессов, файлов, могут находиться в двух состояниях - отмеченном (signaled) и неотмеченном (nonsignaled). В частности, если задача или процесс находятся в состоянии выполнения (то есть работают), соответствующие идентификаторы находятся в неотмеченном состоянии. Когда же задача или процесс завершают свою работу, их идентификаторы отмечаются (то есть переходят в отмеченное состояние).

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

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


{

  CloseHandle(pi.hProcess);

  CloseHandle(pi.hThread);

}

Запущенный таким образом процесс называется отсоединенным (detached). Он будет жить своей жизнью независимо от состояния запустившего его процесса.

Теперь поговорим о коде завершения функции WaitForSingleObject.

В случае ошибки функция возвращает значение WAIT_FAILED. При этом код ошибки можно получить при помощи функции GetLastError.

Если же функция завершилась успешно, она может вернуть одно из следующих трех значений: WAIT_OBJECT_0, WAIT_TIMEOUT или WAIT_ABANDONED.

Если состояние идентификатора объекта, для которого выполнялось ожидание, стало отмеченным, функция фозвращает значение WAIT_OBJECT_0. Таким образом, когда мы ожидаем завершение задачи и задача завершилась “естественным образом”, функция WaitForSingleObject вернет именно это значение.

Если время ожидания, заданное во втором параметре функции WaitForSingleObject истекло, но объект так и не перешел в отмеченное состояние, возвращается значение WAIT_TIMEOUT. Очевидно, при бесконечном ожидании вы никогда не получите этот код завершения.

Код завершения WAIT_ABANDONED  возвращается для объекта синхронизации типа Mutex (его мы рассмотрим позже), который не был освобожден задачей, завершившей свою работу. Таким образом, в этом случае ожидание было отменено и соответствующий объект (Mutex) не перешел в отмеченное состояние.


Содержание раздела