Frage

In C++ Windows-app starte ich mehrere lang laufende Kind-Prozessen (ich verwende derzeit CreateProcess(...) um dies zu tun.

Ich möchte die Kind-Prozesse werden automatisch geschlossen wenn meine Haupt-Prozesse, die Abstürzen oder geschlossen ist.

Aufgrund der Anforderung, die dieser braucht, um zu arbeiten für einen Absturz der "Eltern" ich glaube, dass dies getan werden müssen, mit einigen API/Funktion des Betriebssystems.So, dass alle die "child" - Prozesse bereinigt.

Wie mache ich das?

War es hilfreich?

Lösung

Die Windows-API unterstützt Objekte, die als "Job-Objekten".Der folgende code erzeugt ein "job", das konfiguriert ist, beenden Sie alle Prozesse, wenn die Hauptanwendung beendet wird (wenn die Griffe gereinigt sind).Dieser code sollte nur einmal ausgeführt werden.:

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

Dann, wenn jeder untergeordnete Prozess erstellt wird, führen Sie den folgenden code zum starten jedes Kind, jeder Prozess und fügen Sie es zu dem job-Objekt:

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 HINWEIS:Finden AssignProcessToJobObject immer wieder "Zugriff verweigert" auf Vista wenn Sie Begegnung Zugriff verweigert Probleme mit AssignProcessToObject() auf vista.

Andere Tipps

Eine etwas hackish Lösung wäre für den übergeordneten Prozess zu befestigen, um jedes Kind wie ein debugger (verwenden Sie DebugActiveProcess).Wenn ein debugger beendet alle seine zu debuggende Komponente Prozesse beendet werden, wie gut.

Eine bessere Lösung (vorausgesetzt, Sie schrieb die Kind-Prozesse, als auch) wäre es, die Kind-Prozesse überwachen die Eltern und beenden, wenn es geht Weg.

Windows-Job-Objekten klingt wie ein guter Ort, um zu starten.Der name der Job-Objekt müsste bekannt sein, oder an die Kinder oder Erben, der Griff).Die Kinder müssen merken, wenn der Elternteil stirbt, entweder durch eine fehlgeschlagene IPC - "Herzschlag" oder einfach nur WFMO/WFSO auf den übergeordneten Prozess zu behandeln.An diesem Punkt, dass jeder untergeordnete Prozess könnte TermianteJobObject zu bringen die ganze Gruppe.

Sie können einen separaten watchdog-Prozess ausgeführt wird.Seine einzige Aufgabe ist es, das ansehen des aktuellen Prozess Raum zu erkennen Situationen, wie Sie beschreiben.Es könnte sogar re-launch der ursprünglichen Anwendung nach einem Absturz oder bieten Sie verschiedene Optionen, um die Benutzer sammeln, die debug-Informationen, etc.Versuchen Sie, nur halten Sie es einfach genug, so dass Sie brauchen nicht eine Sekunde watchdog Uhr das erste ein.

Sie würden wahrscheinlich haben, um eine Liste der Prozesse, die Sie starten, und töten Sie eins nach dem anderen, wenn Sie das Programm beenden.Ich bin nicht sicher, dass die Besonderheiten, dies zu tun, in C++, aber es sollte nicht zu schwierig sein.Der schwierige Teil würde wahrscheinlich dafür sorgen, dass die untergeordneten Prozesse heruntergefahren sind im Falle von einem Absturz der Anwendung..Net hat die Fähigkeit zu fügen Sie eine Funktion hinzu, das aufgerufen wird, wenn eine nicht behandelte Ausnahme Auftritt.Ich bin mir nicht sicher, ob C++ bietet die gleichen Funktionen.

Sie konnte Kapseln jeden Prozess in einem C++ - Objekt und halten Sie eine Liste von Ihnen in den globalen Gültigkeitsbereich.Die Destruktoren Herunterfahren können jede Prozess.Das wird funktionieren, wenn das Programm beendet normalerweise aber er abstürzt, sind alle Wetten ab.

Hier ist ein grobes Beispiel:

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

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

private:
    HANDLE _hProcess;
};

std::list<myprocess> allprocesses;

Dann, Wann immer Sie starten, rufen Sie allprocessess.push_back(hProcess);

Nur aus der Spitze von meinem Kopf:

  • Haben Sie in Betracht gezogen, die Verwendung von threads statt Prozessen?
  • Versuchen Sie, übergeben Sie das handle des dem Haupt-thread/Prozess die Kind-Prozesse, und lassen Sie Sie darauf warten, dass Griff.Dies funktioniert für Fäden, als das warten auf ein thread-handle wartet, bis der thread abgeschlossen ist und beendet sich.Auch nicht sicher, wenn es wird Arbeit für Prozesse, sollten überprüfen, MSDN, um dies zu überprüfen.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top