Дочірні процеси - студопедія
При розробці програми часто буває потрібно, щоб якусь операцію виконував інший блок коду. Тому - хочеш, не хочеш - доводиться постійно викликати функції або підпрограми. Але виклик функції призводить до припинення виконання основного коду програми до повернення з викликаної функції Альтернативний спосіб - передати виконання якоїсь операції іншому потоку в межах даного процесу (потік, зрозуміло, потрібно спочатку створити). Це дозволить основного коду програми продовжити роботу в той час, як додатковий потік буде виконувати іншу операцію. Прийом дуже зручний, але, коли основному потоку буде потрібно дізнатися результати роботи іншого потоку, не уникнути проблем, пов'язаних із синхронізацією.
Якщо необхідно створити новий процес і змусити його виконати будь-які опе рації і дочекатися їх результатів, можна використовувати приблизно такий код:
У цьому фрагменті коду ми створили новий процес і, якщо це пройшло успішно, викликали функцію WaitForSingleObject:
DWORD WaitForSingleObject (HANDLE hObject, DWORD dwTimeOut);
Функція затримує виконання коду до тих пір, поки об'єкт, який визначається параметром hObject, що не перейде у вільний (незайняте) стан. Об'єкт «процес» переходить в такий стан при його завершенні З цього виклик WaitForSingleObject призупиняє виконання потоку батьківського процесу до завершення породженого їм процесу. Коли WaitForSingleObject поверне управління, можна узнаеть код завершення дочірнього процесу через функцію Get ExitCodeProcess.
Звернення до CloseHandle в наведеному вище фрагменті коду змушує систему зменшити значення лічильників об'єктів «потік» і «процес» до нуля і тим самим звільнити пам'ять, займану цими об'єктами.
Неважко помітити, що в цьому фрагменті описатель об'єкта ядра "первинний потік" (належить дочірньому процесу) був закритий відразу після повернення з CreateProcess. Це не призводить до завершення первинного потоку дочірнього процесу - просто зменшує лічильник, пов'язаний зі згаданим об'єктом. А ось чому це робиться - і, до речі, навіть рекомендується робити - саме так, стане ясно з про стого прикладу. Припустимо, первинний потік дочірнього процесу породжує ще один потік, а сам після цього завершується. У цей момент система може вивільнити об'єкт "первинний потік" дочірнього процесу з пам'яті, якщо у батьківського процесу немає описателя даного об'єкта. Але якщо батьківський процес має таким описателем, система не зможе видалити цей об'єкт з пам'яті до тих пір, поки і батьківський процес не закриє його описувач.