Детский процесс живет вечно

1

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

using (Process process = process.Start(startInfo))
{
    if (!process.WaitForExit(timeOutMilliSeconds))
    {
        if (!process.HasExited())
        {
            process.Kill();
        }
    }
}

Детский процесс - это процессор с интенсивным вычислением CPU (решатель SAT). Моя основная программа написана на C# и разработана с использованием 64-разрядной версии Visual Studio 2013 и Windows 7.

В большинстве случаев приведенный выше код работает и завершается окончательное завершение процесса. Но в около 5% случаев process.Kill() не имеет видимого эффекта. Детский процесс остается активным.

Я попытался запустить дочерний процесс с более низким приоритетом. Я также попытался приостановить его, прежде чем убить его. Вызов TASKKILL/F как внешнего инструмента также не всегда помог. Я заметил, что проблема не возникает для всех решателей SAT. У меня есть права администратора, но не запускайте основную программу как Администратор.

Что я могу сделать для надежного завершения дочернего процесса моего приложения?

Отредактировано:
Помимо превышения их бюджета тайм-аута, дочерние процессы ведут себя вполне нормально и могут быть убиты вручную с помощью Process Explorer (без повышения уровня администратора). Вопрос заключается в том, как убедиться, что ни один процесс не будет запущен после таймаута.

Временное решение:
Я применил тайм-аут с использованием VC++ 2013. Вместо прямого вызова дочернего процесса я теперь вызываю свой инструмент, который в свою очередь вызывает дочерний процесс. Инструмент использует CreateProcess() и TerminateProcess() для запуска и остановки дочернего процесса. Вероятно, можно вызвать CreateProcess() и TerminateProcess() из программы C# напрямую, не создавая дополнительный процесс.
Обходной путь не изящный, но он решает мою проблему.

  • 1
    В Windows не все операции ввода-вывода можно отменить. Процессы могут попасть в неубиваемое состояние зомби, если они имеют невыполненный IO выдающийся. Это очень редко, хотя.
  • 0
    Из документации для Kill : «Метод Kill выполняется асинхронно. После вызова метода Kill вызовите метод WaitForExit, чтобы дождаться завершения процесса, или проверьте свойство HasExited, чтобы определить, завершился ли процесс.
Показать ещё 2 комментария
Теги:
process
sat-solvers

1 ответ

0

Я создал библиотеку управления дочерними процессами, где отслеживается родительский процесс и дочерний процесс из-за двунаправленного WCF-канала. Если либо дочерний процесс завершается, либо прерывается родительский процесс, он уведомляется. Существует также доступный помощник отладчика, который автоматически присоединяет отладчик VS к запущенному дочернему процессу.

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

Сайт проекта:

http://www.crawler-lib.net/child-processes

Пакеты NuGet:

https://www.nuget.org/packages/ChildProcesses https://www.nuget.org/packages/ChildProcesses.VisualStudioDebug/

  • 0
    В моем приложении дочерние процессы - это внешние сторонние процессы .exe, которые я не могу изменить. Я просто могу использовать обычные механизмы Windows, чтобы наблюдать за состоянием процесса и выдавать команды kill. Возможно, я не совсем понимаю ваш подход, но он не выглядит применимым к моему делу.
  • 0
    О, я думал, что дочерний процесс также был написан вами на C #. На самом деле моего подхода недостаточно для сторонних процессов. Вы пытались прекратить свой процесс, не убивая его. Уничтожение процесса может привести к блокировке определенного ресурса и не всегда возможно.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню