71 votes

Comment puis-je détruisent automatiquement les processus enfants dans Windows?

En C++ application Windows, je lance plusieurs long de l'exécution de processus enfants (actuellement j'utilise la fonction CreateProcess(...) pour ce faire.

Je veux que le processus enfant sera automatiquement fermée si mes principaux processus se bloque ou est fermé.

En raison de l'exigence que cela doit travailler pour un crash de la "mère", je crois que cela devrait être fait en utilisant l'API/fonctionnalité du système d'exploitation. Afin que tous les "enfants" des processus de nettoyage.

Comment dois-je faire?

85voto

jm. Points 7092

L'API Windows prend en charge les objets appelés "Objets". Le code suivant va créer un "travail" qui est configuré pour arrêter tous les processus de l'application principale se termine (lorsque les poignées sont nettoyées). Ce code ne doit être exécuté qu'une fois.:

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);
    }
}

Ensuite, lors de chaque processus enfant est créé, exécutez le code suivant pour lancer à chaque enfant de chaque processus et de l'ajouter à l'objet de travail:

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 NOTE: Voir AssignProcessToJobObject toujours revenir "accès refusé" sur Vista si vous rencontrez des refus d'accès des problèmes avec AssignProcessToObject() sur vista.

5voto

Rob Walker Points 25840

Un peu hackish solution serait que le processus père d'associer à chaque enfant comme un débogueur (utiliser DebugActiveProcess). Lorsqu'un débogueur met fin à tous ses programme débogué les processus sont terminés ainsi.

Une meilleure solution (en supposant que vous avez écrit, l'enfant, le processus d') serait d'avoir l'enfant, les processus de surveiller la mère et de sortie si elle s'en va.

3voto

Adam Mitz Points 4540

Windows Objets semble être un bon endroit pour commencer. Le nom de l'Objet de Travail devrait être bien connu, ou transmis à des enfants (ou d'hériter de la poignée). Les enfants auraient besoin d'être d'avis quand la mère meurt, soit par l'intermédiaire d'un échec de la CIB "battement de cœur" ou tout simplement WFMO/WFSO sur le parent du handle de processus. À ce point, tout le processus enfant pourrait TermianteJobObject mettre à bas l'ensemble du groupe.

1voto

Pedro Points 486

Vous pouvez garder un chien de garde processus en cours d'exécution. Sa seule tâche est de regarder le processus actuel de l'espace de repérer de telles situations que vous décrivez. Il pourrait même relancer l'application d'origine après un crash ou de fournir des différentes options pour l'utilisateur, de recueillir des informations de débogage, etc. Juste essayer de le garder assez simple de sorte que vous n'avez pas besoin d'un deuxième chien de garde de regarder le premier.

-2voto

Kibbee Points 36474

Vous auriez probablement à garder une liste des processus de commencer, et de les tuer un par un lorsque vous quittez votre programme. Je ne suis pas sûr de la spécificité de le faire en C++, mais il ne devrait pas être dur. La partie la plus difficile sera probablement s'assurer que les processus enfants sont à l'arrêt dans le cas d'un crash de l'application. .Net a la possibilité d'ajouter une fonction qui est appelée lorsqu'une exception non gérée se produit. Je ne suis pas sûr si C++ offre les mêmes capacités.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X