Jak automatycznie zniszczyć procesy potomne w systemie Windows?

W aplikacji C++ Windows uruchamiam kilka długo działających procesów potomnych (obecnie używam CreateProcess (...), aby to zrobić.

Chcę, aby procesy potomne były automatycznie zamykane , Jeśli moje główne procesy ulegną awarii lub zostaną zamknięte.

Ze względu na wymóg, że musi to działać w przypadku awarii "rodzica", uważam, że musi to być zrobione przy użyciu jakiegoś API / funkcji systemu operacyjnego. Tak, że wszystkie procesy" dziecko " są oczyszczone.

How do I do to?

Author: Tshepang, 2008-09-10

7 answers

Windows API obsługuje obiekty o nazwie "Job Objects". Poniższy kod utworzy "zadanie", które jest skonfigurowane tak, aby zamknąć wszystkie procesy po zakończeniu głównej aplikacji (gdy jej uchwyty są oczyszczone). Ten kod powinien być uruchomiony tylko raz.:

HANDLE ghJob = CreateJobObject( NULL, NULL); // GLOBAL
if( ghJob == NULL)
{
    ::MessageBox( 0, "Could not create job object", "TEST", MB_OK);
}
else
{
    JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };

    // Configure all child processes associated with the job to terminate when the
    jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
    if( 0 == SetInformationJobObject( ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)))
    {
        ::MessageBox( 0, "Could not SetInformationJobObject", "TEST", MB_OK);
    }
}

Następnie po utworzeniu każdego procesu potomnego wykonaj następujący kod, aby uruchomić każdy proces potomny i dodać go do obiektu zadania:

STARTUPINFO info={sizeof(info)};
PROCESS_INFORMATION processInfo;

// Launch child process - example is notepad.exe
if (::CreateProcess( NULL, "notepad.exe", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
{
    ::MessageBox( 0, "CreateProcess succeeded.", "TEST", MB_OK);
    if(ghJob)
    {
        if(0 == AssignProcessToJobObject( ghJob, processInfo.hProcess))
        {
            ::MessageBox( 0, "Could not AssignProcessToObject", "TEST", MB_OK);
        }
    }

    // Can we free handles now? Not sure about this.
    //CloseHandle(processInfo.hProcess); 
    CloseHandle(processInfo.hThread);
}

VISTA Uwaga: Patrz AssignProcessToJobObject zawsze zwraca "Access denied" na Vista Jeśli napotkasz problemy z odmową dostępu z AssignProcessToObject () NA vista.

 65
Author: jm.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-27 14:53:35

Jednym z nieco hakerskich rozwiązań byłoby dołączenie procesu macierzystego do każdego dziecka jako debugera (użyj DebugActiveProcess). Gdy debugger zakończy wszystkie procesy debuggera również zostaną zakończone.

Lepszym rozwiązaniem (zakładając, że napisałeś również procesy potomne) byłoby to, aby procesy potomne monitorowały rodzica i kończyły pracę, jeśli zniknie.

 5
Author: Rob Walker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-10 00:28:13

Obiekty zadań systemu Windows brzmią jak dobre miejsce na początek. Nazwa obiektu pracy musi być dobrze znana lub przekazywana dzieciom (lub dziedziczyć uchwyt). Dzieci muszą być zauważone, gdy rodzic umiera, albo przez nieudane IPC "heartbeat" lub po prostu wfmo/wfso na uchwycie procesu rodzica. W tym momencie każdy proces potomny może doprowadzić do upadku całej grupy.

 3
Author: Adam Mitz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-10 06:24:54

Można zachować osobny proces watchdog uruchomiony. Jego jedynym zadaniem jest obserwowanie bieżącej przestrzeni procesu, aby dostrzec sytuacje takie jak opisujesz. Może nawet ponownie uruchomić oryginalną aplikację po awarii lub zapewnić różne opcje dla użytkownika, zbierać informacje o debugowaniu itp. Po prostu postaraj się, aby było to wystarczająco proste, abyś nie potrzebował drugiego watchdoga do oglądania pierwszego.

 0
Author: Pedro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-10 00:25:40

Prawdopodobnie będziesz musiał zachować listę procesów, które uruchamiasz, i zabić je jeden po drugim po wyjściu z programu. Nie jestem pewien specyfiki robienia tego w C++, ale nie powinno to być trudne. Trudną częścią byłoby prawdopodobnie upewnienie się, że procesy potomne są zamykane w przypadku awarii aplikacji. . Net ma możliwość dodania funkcji, która jest wywoływana, gdy wystąpi nieobsługiwany wyjątek. Nie jestem pewien, czy C++ oferuje te same możliwości.

 -2
Author: Kibbee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-10 00:19:50

Można zamknąć każdy proces w obiekcie C++ i zachować ich listę w globalnym zasięgu. Destruktory mogą wyłączyć każdy proces. To będzie działać dobrze, jeśli program wyjdzie normalnie, ale to się zawiesza, wszystkie zakłady są wyłączone.

Oto przybliżony przykład:

class myprocess
{
public:
    myprocess(HANDLE hProcess)
        : _hProcess(hProcess)
    { }

    ~myprocess()
    {
        TerminateProcess(_hProcess, 0);
    }

private:
    HANDLE _hProcess;
};

std::list<myprocess> allprocesses;

Wtedy, gdy uruchomisz jeden, wywołaj allprocessess.push_back (hProcess);

 -2
Author: Adam Pierce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-10 00:34:11

Prosto z głowy:

  • czy rozważałeś użycie wątków zamiast procesów?
  • spróbuj przekazać rękojeść głównego wątku / procesu procesom potomnym i zmusić je do oczekiwania na ten rękojeść. Działa to dla wątków, ponieważ oczekiwanie na uchwyt wątku czeka, aż wątek zakończy się i zakończy. Nie jest zbyt pewien, czy to będzie działać dla procesów, należy sprawdzić MSDN, aby to zweryfikować.
 -4
Author: Daemin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-10 04:20:08