Как я автоматически уничтожаю дочерние процессы в Windows?

С Коллекции Eclipse (ранее коллекции GS ) будет работать метод removeIf, определенный на MutableCollection :

MutableList list = Lists.mutable.of(1, 2, 3, 4, 5);
list.removeIf(Predicates.lessThan(3));
Assert.assertEquals(Lists.mutable.of(3, 4, 5), list);

С синтаксисом Java 8 Lambda это можно записать следующим образом:

MutableList list = Lists.mutable.of(1, 2, 3, 4, 5);
list.removeIf(Predicates.cast(integer -> integer < 3));
Assert.assertEquals(Lists.mutable.of(3, 4, 5), list);

Необходим вызов Predicates.cast(), потому что по умолчанию removeIf метод был добавлен на интерфейс java.util.Collection в Java 8.

Примечание: я являюсь коммиттером для коллекций Eclipse .

64
задан tshepang 18 February 2014 в 06:38
поделиться

7 ответов

Windows API поддерживает объекты, названные "Объекты Задания". Следующий код создаст "задание", которое настроено для закрытия всех процессов, когда главное приложение заканчивается (когда его дескрипторы очищены). Этот код должен только быть выполнен однажды.:

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

Тогда, когда каждый дочерний процесс будет создан, выполните следующий код, чтобы запустить каждый дочерний элемент каждый процесс и добавить его к объекту задания:

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: См. , AssignProcessToJobObject всегда возвращают "доступ запрещен" на Vista при обнаружении с проблемами доступа запрещен с AssignProcessToObject () на перспективе.

73
ответ дан KindDragon 24 November 2019 в 16:00
поделиться

Один несколько hackish решение был бы для родительского процесса для присоединения к каждому ребенку как отладчик (использование DebugActiveProcess). Когда отладчик завершается, все его процессы отлаживаемой программы завершаются также.

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

5
ответ дан Rob Walker 24 November 2019 в 16:00
поделиться

Windows Job Objects походит на хорошее место для запуска. Название Объекта Задания должно было бы быть известным, или передало детям (или наследуйте дескриптор). Дети должны были бы быть уведомлением, когда родитель умирает, или через обанкротившуюся IPC "heartbeat" или просто через WFMO/WFSO на дескрипторе процесса родителя. В той точке любой дочерний процесс мог TermianteJobObject для перевода в нерабочее состояние целой группы.

3
ответ дан Adam Mitz 24 November 2019 в 16:00
поделиться

Можно поддерживать отдельный сторожевой процесс в рабочем состоянии. Его единственная задача смотрит, пространство текущего процесса для определения ситуаций как Вы описывают. Это могло даже повторно запустить исходное приложение после катастрофического отказа или предоставить различные возможности пользователю, собрать отладочную информацию и т.д. Просто попытайтесь сохранить его достаточно простым так, чтобы Вам не был нужен второй сторожевой таймер для наблюдения первого.

0
ответ дан Pedro 24 November 2019 в 16:00
поделиться

Необходимо было бы, вероятно, сохранить список процессов, которые Вы запускаете и уничтожаете их один за другим при выходе из программы. Я не уверен в специфических особенностях выполнения этого в C++, но это не должно быть твердо. Трудная часть, вероятно, гарантировала бы, что дочерние процессы являются завершением работы в случае сбоя приложения..Net имеет способность добавить функцию, которые добираются, звонил, когда необработанное исключение происходит. Я не уверен, предлагает ли C++ те же возможности.

-2
ответ дан Kibbee 24 November 2019 в 16:00
поделиться

Вы могли инкапсулировать каждый процесс в объекте C++ и сохранить список их в глобальной области видимости. Деструкторы могут закрыть каждый процесс. Это будет хорошо работать, если программа будет обычно выходить, но это, который это разрушает, все ставки, выключено.

Вот грубый пример:

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

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

private:
    HANDLE _hProcess;
};

std::list<myprocess> allprocesses;

Тогда каждый раз, когда Вы запускаетесь один, назовите allprocessess.push_back (hProcess);

-2
ответ дан Adam Pierce 24 November 2019 в 16:00
поделиться

Просто первое, что пришло на ум:

  • Вы рассмотрели использование потоков вместо процессов?
  • Попытка, передающая дескриптор основного потока/процесса к дочерним процессам и, заставляют их ожидать на том дескрипторе. Это работает на потоки, поскольку ожидающий на дескрипторе потока ожидает, пока тот поток не завершается и выходит. Не слишком уверенный, если это будет работать на процессы, должен проверить MSDN для проверки этого.
-4
ответ дан Daemin 24 November 2019 в 16:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: