CreateProcess такой, что дочерний процесс убивается, когда убит родитель?

можно ли позвонить является CreateProcess такое, что убийство родительского процесса автоматически убивает дочерний процесс?

возможно, используя Создать Флаги Процесса?

редактировать
Решение состоит в том, чтобы создать объект задания, поместить в объект задания как родительский, так и дочерний. Когда убивают родителя, убивают и ребенка. У меня есть код: убить дочерний процесс, когда родительский процесс убит Принять к сведению комментарий @wilx о унаследованных дескрипторах.

6 ответов


использование заданий как Нил говорит ИМХО лучший способ. Вы можете убить дочерние процессы, когда процесс владения заданием умирает, установив JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE на объекте задания с помощью SetInformationJobObject(). Дескриптор объекта задания будет закрыт, когда родительский процесс завершится / завершится. Для этого необходимо, чтобы дескриптор задания был не унаследован дочерними процессами. Если вы хотите отслеживать также процессы grand-child, вам придется создайте приостановленные дочерние процессы, добавьте их в объект задания и только затем запустите.


лучшее, что вы можете сделать, это поместить оба процесса в одну работу, так что убийство задания убивает оба процесса.


вам нужен дочерний процесс, чтобы быть убил, или просто обнаружить выход родительского процесса, чтобы он мог закончиться чисто? Родительский процесс может создать наследуемый дескриптор для себя, который затем ребенок может передать в WaitForMultipleObjects(Ex) вместе со своими объектами.

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

это близко соответствует поведению Unix, в котором ребенок не убивается, когда его родитель умирает, он обычно выходит в ответ на SIGHUP (но он может обрабатывать этот сигнал и реализовывать любое поведение). В Linux Родительский PID сироты изменяется на 1 (init).


Я думаю DEBUG_PROCESS или DEBUG_ONLY_THIS_PROCESS сделал бы это, как почти случайный побочный эффект. Windows не создает процессы в дереве, как это делают Unix-подобные системы.


разный подход

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

Примечание: теперь, это не для премии творчества. вот это: An приложение, которое необходимо завернуть, однако это устаревшее приложение и не может быть изменено или переписано удовлетворительным образом. Нам нужно было поддерживать эту систему в рабочем состоянии, перехватив при этом ее выходы.

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

если вы контролируете ребенка процессы и иметь введенную DLL в любом случае, вы можете расширить эту DLL на мониторинг родительского процесса, чтобы проверить, работает ли он. Если нет,ExitProcess.

Если вам не нужна DLL в дочернем процессе, другие решения, скорее всего, намного лучше.


вы можете передать parentProcessID через, например, раздел реестра, который вы уже используете в своем приложении. Или вы можете передать командную строку, если это не сломает ребенка процесс.

Это должно работать в своем собственном потоке. У моей DLL было два потока: этот код здесь и код управления и связи.

DLL

bool IsProcessRunning(HANDLE hProcess)
{
    DWORD exitCode;
    GetExitCodeProcess(hProcess, &exitCode);
    return exitCode == STILL_ACTIVE;
}

bool WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        int parentProcessID = [...]

        HANDLE parentProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, parentProcessID);
        while (IsProcessRunning(parentHandle)) Sleep(100);
        ExitProcess(0);
    }

    return true;
}

Не знаю о windows, но это будет работать на linux: prctl (PR_SET_PDEATHSIG, SIGHUP);