Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как правильно закрыть процесс созданый с помощю 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. При закрытии процесса все его потоки уничтожаются автоматически. При завершении главного потока процесс также завершается автоматически.


Наверх

Титульная страница Поиск, карта сайта Написать письмо