Форум: "WinAPI";
Текущий архив: 2004.01.23;
Скачать: [xml.tar.bz2];
ВнизКак правильно закрыть процесс созданый с помощю CreateProcess Найти похожие ветки
← →
Closer (2003-11-18 01:03) [0]Есть 2 варианта закрытия процесса:
1.
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
2.
TerminateProcess(pi.hProcess,NO_ERROR);
1. Какой из них наиболее правильный?
2. И необходимо ли в первом варианте закрывать Thread и почему?
3. Что закрывать первым: процесс или Thread?
← →
Внук (2003-11-18 10:11) [1]Первый вариант - это не закрытие процесса, а освобождение описателя.
Можно использовать TerminateProcess, либо послать сообщение WM_QUIT. При закрытии процесса все его потоки уничтожаются автоматически. При завершении главного потока процесс также завершается автоматически.
← →
Digitman (2003-11-18 10:58) [2]
> При завершении главного потока процесс также завершается
> автоматически
с чего ты взял ? процесс завершается после завершения ВСЕХ код.потоков, существующих в его контексте, а не только основного.
т.е. необходимым и достаточным условием завершения корректного процесса является корректное же завершение всех его код.потоков
о корректности же здесь вообще не идет речи, ибо TerminateProcess() есть аварийный метод снятия процесса с выполнения, при котором все его кодовые потоки (сколько бы их ни было) будут так же неявно аварийно терминированы.
← →
Внук (2003-11-18 11:12) [3]>>Digitman © (18.11.03 10:58) [2]
Кроме первого абзаца, все остальное без сомнения.
Насколько я помню Рихтера, поток, созданный при старте процесса, является "главным", и его завершение влечет завершение всего процесса вместе с остальными потоками. Но книги под рукой нет, пусть Игорь нас рассудит :)
← →
Внук (2003-11-18 11:15) [4]Игорь рассудил. Я не прав :)
← →
Внук (2003-11-18 11:16) [5]Удалено модератором
Примечание: Offtopic
← →
Closer (2003-11-18 13:09) [6]Итак, подводя итог, получается что(поправте если я ошибусь):
1. Если я хочу аварийно завершить созданый мной процесс, то я пишуTerminateProcess(pi.hProcess,NO_ERROR);
2 Если я ПРОСТО хочу завершить созданый мною процесс, то я пишуPostThreadMessage(pi.dwThreadId,WM_QUIT,0,0);
Использование же первого предложеного мной 1 варианта ведёт к закрытию описателей на процесс и его поток, и не влечёт его закрытие.
P.S.
Я испытал все 3 способа закрытия процесса на примере моей программе http://closer.at.tut.by/TestCmd2.zip, сработал только TerminalProcess :)
Наличие процесса проверял с помощю ProcessExplorer http://closer.at.tut.by/procexpnt.zip
В чем может быть проблемма (моя программа перенаправляет ввод/вывод консольного приложения(Cmd.exe) )?
← →
Digitman (2003-11-18 13:21) [7]
> 1. Если я хочу аварийно завершить созданый мной процесс,
> то я пишу TerminateProcess(pi.hProcess,NO_ERROR);
да, если имеешь на то соответствующие права
> Если я ПРОСТО хочу завершить созданый мною процесс, то я
> пишу PostThreadMessage(pi.dwThreadId,WM_QUIT,0,0);
не факт. в общем случае 100%-й гарантии того, что это решит поставленную задачу, нет.
> Использование же первого предложеного мной 1 варианта ведёт
> к закрытию описателей на процесс и его поток, и не влечёт
> его закрытие.
так точно.
> В чем может быть проблемма (моя программа перенаправляет
> ввод/вывод консольного приложения(Cmd.exe) )?
раз ты это делаешь, то просто посылай конс.окну команду "EXIT" ...
разумеется, на "EXIT" консоль отреагирует только если она ожидает ввода ком.строки
← →
Closer (2003-11-18 13:47) [8]Да, как-то об "EXIT", я и не подумал. :) Cmd.exe закрывает без проблем.
Я подумал и решил, что более правильно для меня в данной ситуации закрывать консоль всё же с помощью TerminateProcess, т.к. консоль действительно может быть не готова к вводу ком. строки.
ОГРОМНОЕ СПАСИБО ЗА ПОМОЩЬ.
← →
y-soft (2003-11-18 15:35) [9]>Digitman © (18.11.03 10:58) [2]
Есть еще одно условие, про которое редко вспоминают - должны быть освобождены все внешние ссылки на процесс из других процессов (закрыты его описатели), т.е. возможен случай, когда все потоки процесса уже завершились, а он формально существует...
У Рихтера, кстати, про это тоже есть :)
← →
Digitman (2003-11-18 15:49) [10]
> возможен случай, когда все потоки процесса уже завершились,
> а он формально существует
да, существует ... но не в списке работающих процессов, а в других сист.структурах ... здесь речь идет просто о потенциальной утечке ресурсов, которая, впрочем не страшна : ресурсы эти будут освобождены вместе с завершением процесса, "бросившего" незакрытую им явно ссылку
← →
y-soft (2003-11-18 16:04) [11]>Digitman © (18.11.03 15:49) [10]
здесь речь идет просто о потенциальной утечке ресурсов
IMHO не только - сделано весьма разумно.
Например, CreateProcess вернула действительный описатель, а процесс по каким-то причинам вдруг завершился. Т.к. описатель процесса остается действительным, с ним можно еще работать. Например запросить код выхода GetExitCodeProcess(hProcess, ExitCode) и убедиться, что процесс завершен (ExitCode <> STILL_ACTIVE), или просто передать его в функцию ожидания (она не завершится с кодом WAIT_FAILED, а просто вернет WAIT_OBJECT_0)...
← →
Digitman (2003-11-18 16:34) [12]
> Т.к. описатель процесса остается действительным, с ним
> можно еще работать
не спорю. на то описатель и был получен и зафиксирован.
← →
Closer (2003-11-18 18:05) [13]А после вызова
TerminateProcess(pi.hProcess,NO_ERROR);
описатель остаётся действительным?
Т.е. надо ли его потом закрыть с помощьюCloseHandle(pi.hProcess);
?
← →
panov (2003-11-18 18:12) [14]>Closer © (18.11.03 18:05) [13]
Дескриптор используется в твоей программе, поэтому его надо закрывать.
← →
y-soft (2003-11-18 18:44) [15]>Closer © (18.11.03 18:05) [13]
MSDN настоятельно рекомендует закрывать:)
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.01.23;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.006 c