Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Дочерние процессы - часть 2


Если Вы хотите создать новый процесс, заставить его выполнить какис-либо опе рации и дождаться их результатов, напишите примерно такой код

PROCESS_INFORMATION pi;
DWORD dwExitCode;

// порождаем дочерний процесс
BOOL fSuccess = CreateProcess(..., &pi};

if (fSuccess) {

// закрывайте описатель потока, как только необходимость в нем отпадает!
CloseHandle(pi hThread);


// приостанавливаем выполнение родительского процесса,
// пока не завершится дочерний процесс
WaitForSingleObject(pi hProcess, INFINlTI);

// дочерний процесс завершился; получаем код его завершения
GetExitCodeProcess(pi.hProcess, &dwExitCode);

// закрывайте описатель процесса, как только необходимость в нем отпадает!
CloseHandle(pi.hProcess);

}

В этом фрагменте кода мы создали новый процесс и, если это прошло успешно, вызвали функцию WaitForSingleQbject

DWORD WaitForSingleObject(HANDLE hObject, DWORD dwTimeOut);

Подробное рассмотрение данной функции мы отложим до главы 0, а сейчас ог раничимся одним соображением Функция задерживает выполнение кода до тех пор,

пока объект, определяемый параметром bObject, не перейдет в свободное (незанятое) состояние. Объект "процесс" переходит в такое состояние при его завершении По этому вызов WaitForSingleObject приостанавливает выполнение потока родительского процесса до завершения порожденного им процесса. Когда WaitForSingleObject вернет управление, Вы узнаете код завершения дочернего процесса через функцию Get ExitCodeProcess.

Обращение к CloseHandle в приведенном выше фрагменте кода заставляет систе му уменьшить значения счетчиков объектов "поток" и "процесс" до нуля и тем самым освободить память, занимаемую этими объектами.

Вы, наверное, заметили, что в этом фрагменте я закрыл описатель объекта ядра "первичный поток" (принадлежащий дочернему процессу) сразу после возврата из CreateProcess. Это не приводит к завершению первичного потока дочернего процес са — просто уменьшает счетчик, связанный с упомянутым объектом. А вот почему это делается — и, кстати, даже рекомендуется делать — именно так, станет ясно из про стого примера. Допустим, первичный поток дочернего процесса порождает еще один поток, а сам после этого завершается. В этот момент система может высвободить объект "первичный поток" дочернего процесса из памяти, если у родительского про цесса нет описателя данного объекта. Но если родительский процесс располагает таким описателем, система не сможет удалить этот объект из памяти до тех пор, пока и родительский процесс не закроет его описатель.




Начало  Назад  Вперед



Книжный магазин