![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как правильно закрыть процесс созданый с помощю CreateProcess [D5, WinXP]
Closer © (2003-11-18 01:03:00)
Есть 2 варианта закрытия процесса:
1.
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
2.
TerminateProcess(pi.hProcess,NO_ERROR);
1. Какой из них наиболее правильный?
2. И необходимо ли в первом варианте закрывать Thread и почему?
3. Что закрывать первым: процесс или Thread?
y-soft (2003-11-18 18:44:00) [1]
>Closer © (18.11.03 18:05) [13]
MSDN настоятельно рекомендует закрывать:)
panov (2003-11-18 18:12:00) [2]
>Closer © (18.11.03 18:05) [13]
Дескриптор используется в твоей программе, поэтому его надо закрывать.
Closer (2003-11-18 18:05:00) [3]
А после вызова
TerminateProcess(pi.hProcess,NO_ERROR);описатель остаётся действительным?
Т.е. надо ли его потом закрыть с помощьюCloseHandle(pi.hProcess);?
Digitman (2003-11-18 16:34:00) [4]
> Т.к. описатель процесса остается действительным, с ним
> можно еще работать
не спорю. на то описатель и был получен и зафиксирован.
y-soft (2003-11-18 16:04:00) [5]
>Digitman © (18.11.03 15:49) [10]
здесь речь идет просто о потенциальной утечке ресурсов
IMHO не только - сделано весьма разумно.
Например, CreateProcess вернула действительный описатель, а процесс по каким-то причинам вдруг завершился. Т.к. описатель процесса остается действительным, с ним можно еще работать. Например запросить код выхода GetExitCodeProcess(hProcess, ExitCode) и убедиться, что процесс завершен (ExitCode <> STILL_ACTIVE), или просто передать его в функцию ожидания (она не завершится с кодом WAIT_FAILED, а просто вернет WAIT_OBJECT_0)...
Digitman (2003-11-18 15:49:00) [6]
> возможен случай, когда все потоки процесса уже завершились,
> а он формально существует
да, существует ... но не в списке работающих процессов, а в других сист.структурах ... здесь речь идет просто о потенциальной утечке ресурсов, которая, впрочем не страшна : ресурсы эти будут освобождены вместе с завершением процесса, "бросившего" незакрытую им явно ссылку
y-soft (2003-11-18 15:35:00) [7]
>Digitman © (18.11.03 10:58) [2]
Есть еще одно условие, про которое редко вспоминают - должны быть освобождены все внешние ссылки на процесс из других процессов (закрыты его описатели), т.е. возможен случай, когда все потоки процесса уже завершились, а он формально существует...
У Рихтера, кстати, про это тоже есть :)
Closer (2003-11-18 13:47:00) [8]
Да, как-то об "EXIT", я и не подумал. :) Cmd.exe закрывает без проблем.
Я подумал и решил, что более правильно для меня в данной ситуации закрывать консоль всё же с помощью TerminateProcess, т.к. консоль действительно может быть не готова к вводу ком. строки.
ОГРОМНОЕ СПАСИБО ЗА ПОМОЩЬ.
Digitman (2003-11-18 13:21:00) [9]
> 1. Если я хочу аварийно завершить созданый мной процесс,
> то я пишу TerminateProcess(pi.hProcess,NO_ERROR);
да, если имеешь на то соответствующие права
> Если я ПРОСТО хочу завершить созданый мною процесс, то я
> пишу PostThreadMessage(pi.dwThreadId,WM_QUIT,0,0);
не факт. в общем случае 100%-й гарантии того, что это решит поставленную задачу, нет.
> Использование же первого предложеного мной 1 варианта ведёт
> к закрытию описателей на процесс и его поток, и не влечёт
> его закрытие.
так точно.
> В чем может быть проблемма (моя программа перенаправляет
> ввод/вывод консольного приложения(Cmd.exe) )?
раз ты это делаешь, то просто посылай конс.окну команду "EXIT" ...
разумеется, на "EXIT" консоль отреагирует только если она ожидает ввода ком.строки
Closer (2003-11-18 13:09:00) [10]
Итак, подводя итог, получается что(поправте если я ошибусь):
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) )?
Внук (2003-11-18 11:16:00) [11]
Удалено модератором
Примечание: Offtopic
Внук (2003-11-18 11:15:00) [12]
Игорь рассудил. Я не прав :)
Внук (2003-11-18 11:12:00) [13]
>>Digitman © (18.11.03 10:58) [2]
Кроме первого абзаца, все остальное без сомнения.
Насколько я помню Рихтера, поток, созданный при старте процесса, является "главным", и его завершение влечет завершение всего процесса вместе с остальными потоками. Но книги под рукой нет, пусть Игорь нас рассудит :)
Digitman (2003-11-18 10:58:00) [14]
> При завершении главного потока процесс также завершается
> автоматически
с чего ты взял ? процесс завершается после завершения ВСЕХ код.потоков, существующих в его контексте, а не только основного.
т.е. необходимым и достаточным условием завершения корректногопроцесса является корректноеже завершение всех его код.потоков
о корректности же здесь вообще не идет речи, ибо TerminateProcess() есть аварийный метод снятия процесса с выполнения, при котором все его кодовые потоки (сколько бы их ни было) будут так же неявно аварийно терминированы.
Внук (2003-11-18 10:11:00) [15]
Первый вариант - это не закрытие процесса, а освобождение описателя.
Можно использовать TerminateProcess, либо послать сообщение WM_QUIT. При закрытии процесса все его потоки уничтожаются автоматически. При завершении главного потока процесс также завершается автоматически.