- Как принудительно завершить процесс?
- Функция TerminateProcess
- Завершение процессов и система безопасности Windows NT
- Завершение дерева процессов
- Завершение 16-битных задач в Windows NT
- Заключение
- Обработчики завершения: завершение процессов и потоков
- Читайте также
- Обработчики завершения
- Приоритеты процессов и потоков и планирование выполнения
- Предостережение относительно использования приоритетов потоков и процессов
- Стеки потоков и допустимые количества потоков
- Обработчики прерываний
- Функции-обработчики
- Обработчики прерываний
- 26.2. Основные функции для работы с потоками: создание и завершение потоков
- 1.1.9. Обработчики событий
- Обработчики прерываний
- Взаимосвязь процессов, доменов приложений, контекстов и потоков
- 4.3.1. Обработчики очистки
- 4.6. Сравнение процессов и потоков
- Глава 6. Завершение и код завершения
- Завершение и прекращение выполнения процесса
- Читайте также
- 9.1.5. Завершение процесса
- Завершение процесса
- Завершение процесса
- Завершение выполнения процесса
- 5.12. Завершение процесса сервера
- 7.4 ОЖИДАНИЕ ЗАВЕРШЕНИЯ ВЫПОЛНЕНИЯ ПРОЦЕССА
- Создание, завершение и просмотр учетной записи процесса
- 7.3.2. Концепции, касающиеся основных средств производственного процесса организации Основные средства производственного процесса организации (ППО)
- Завершение процесса, заблокировавшего ресурс
- Завершение процесса с помощью команды KILL
- В завершение
- 3.4. Завершение процесса
- 18.8.2. Прекращение выполнения оператора case
- Завершение
Как принудительно завершить процесс?
Автор: Александр Федотов
Опубликовано: 24.10.2001
Исправлено: 13.03.2005
Версия текста: 1.0
Иногда в программистcкой практике встает задача принудительно завершить посторонний процесс. Например, ваша программа может запускать внешние программы для обработки некоторых форматов файлов. Если внешняя программа не завершается в разумный промежуток времени, ее придется завершить принудительно и сообщить пользователю об ошибке. Прочитав эту статью, вы сможете убивать чужие процессы направо и налево, по одиночке и скопом. Мы будем считать, что нам известен идентификатор процесса, который мы хотим завершить.
Функция TerminateProcess
Для принудительного и безоговорочного завершения процессов в Win32 служит функция TerminateProcess :
Сейчас я обязан сделать
Функцию TerminateProcess следует использовать только в исключительных случаях, когда исчерпаны все другие способы воздействия на процесс, поскольку она не позволяет потокам процесса выполнить очистку или сохранить данные, а также не оповещает загруженные DLL о завершении процесса. |
Я уверен, что это предупреждение вас не остановит. Для того, чтобы воспользоваться функцией TerminateProcess , необходимо получить описатель (handle) процесса. Зная идентификатор процесса, это несложно сделать c помощью функции OpenProcess , в итоге функция принудительного завершения процесса может выглядеть, например, так:
Завершение процессов и система безопасности Windows NT
Если вы воспользуетесь функцией KillProcess , то обнаружите, что хотя она замечательно работает в Windows 95/98, в Windows NT она не может завершить некоторые процессы, потому что OpenProcess возвращает ошибку ERROR_ACCESS_DENIED. В частности, это происходит при попытке остановить процессы системных служб и некоторых DCOM-серверов. Как вы наверное уже догадываетесь, все дело в правах доступа.
Как и любой объект ядра, объект процесса защищен дескриптором безопасности, который проверяется всякий раз, когда открывается описатель процесса. Для разных видов процессов дескриптор безопасности инициализируется по-разному. Вы можете воспользоваться тестовой программой Process Viewer для изучения дескрипторов безопасности процессов. Так, вы можете обнаружить, что дескриптор безопасности для интерактивных процессов выглядит так:
Интерактивный пользователь | Полный доступ |
СИСТЕМА | Полный доступ |
в то время как для системных служб, работающих в контексте системной логон-сессии, дескриптор безопасности выглядит иначе:
Администраторы | Чтение |
СИСТЕМА | Полный доступ |
Теперь ясно, почему OpenProcess не позволяет открыть описатель процесса системной службы с правами PROCESS_TERMINATE, даже если вызывающий пользователь является администратором компьютера. Это может показаться странным, почему администратор компьютера не может остановить любой процесс в системе. На самом деле, такая возможность у него есть, и заключается она в наличии привилегии SE_DEBUG_NAME.
Все привилегии, которые имеет пользователь, могут находиться в двух состояниях: выключенном, неактивном, и включенном, активном состоянии. Администраторы компьютера имеют привилегию SE_DEBUG_NAME, но по умолчанию она находится в выключенном состоянии и не оказывает влияния на работу OpenProcess . Когда эта привилегия включена, вызывающий поток может открывать описатели процессов с любыми правами доступа, вне зависимости от того, какой дескриптор безопасности назначен объекту процесса. Это как раз то, что нам нужно.
Ниже приведен модифицированный код функции KillProcess , которая при необходимости включает привилегию SE_DEBUG_NAME, чтобы получить описатель процесса.
Модифицированный вариант функции KillProcess сначала пытается открыть описатель процесса без использования привилегии SE_DEBUG_NAME. Если это у него не получается, он включает привилегию, получает описатель процесса и затем восстанавливает привилегию в исходное состояние.
Теперь с помощью функции KillProcess можно убить практически любой процесс в системе, если, конечно, вы являетесь администратором компьютера. Чтобы проверить новый вариант функции в деле, вы можете воспользоваться тестовым приложением Process Viewer, которое теперь умеет завершать процессы. Например, можно остановить процесс Winlogon и через несколько секунд увидеть синий экран с надписью STOP 0xC000021A (не забудьте сохранить все открытые документы, прежде чем это сделать).
Завершение дерева процессов
Некоторое время назад мой коллега по работе попросил меня написать утилиту, аналогичную утилите kill в Unix. Он занимался переносом каких-то скриптов из Unix на Windows NT и ему нужна была такая утилита. Использовать утилиту, поставляемую в составе Windows NT Resource Kit, он не мог по лицензионным (а может, и религиозным) соображениям.
Я быстро оформил функцию KillProcess в виде небольшого консольного приложения и отправил ему. Коллега был приятно удивлен скорости, с которой я выполнил его просьбу, однако он отметил, что моя версия kill работает не так, как аналог из Unix. В Unix, kill завершает не только сам процесс, но и все дочерние процессы, которые были запущены из него прямо или косвенно (так называемое дерево процессов ). Моя же версия работала как kill -9 , когда завершается только указанный процесс. Таким образом, встала задача повторить поведение Unix kill на Windows NT.
Чтобы завершить все процессы в дереве, необходимо каким-либо образом отследить отношения родитель — потомок между процессами. В Windows 9x/Me и Windows 2000/XP это позволяют сделать функции перечисления процессов из ToolHelp32 API, в частности поле th32ParentProcessID структуры PROCESSENTRY32 содержит идентификатор родительского процесса. В Windows NT 4.0 эту информацию можно получить с помощью официально недокументированной функции ZwQuerySystemInformation . (Подробнее о функциях перечисления процессов рассказано в статье Как получить список запущенных процессов?)
Ниже приведен код функции KillProcessEx , которая позволяет завершать как отдельный процесс, так и целое дерево процессов. Если вы читали статью про перечисление процессов, то найдете много знакомых кусков кода в этой функции.
Используя функцию KillProcessEx , я смог написать утилиту PKILL, которая более точно соответствует своему Unix-аналогу. Эта утилита прилагается в качестве тестового приложения к данной статье.
Завершение 16-битных задач в Windows NT
Рассмотрение вопроса о завершении процессов не будет полным, если мы не затронем тему 16-битных задач на Windows NT. Для завершения 16-битных задач VDMDBG.DLL предоставляет функцию VDMTerminateTaskWOW :
Параметры этой функции говорят сами за себя. Тестовое приложение Process Viewer использует ее для завершения 16-битных задач на Windows NT.
Заключение
Таким образом, теперь вы во всеоружии готовы завершить любой процесс. Но, как и всякое оружие, используйте возможность принудительного завершения процессов с осторожностью.
Обработчики завершения: завершение процессов и потоков
Обработчики завершения: завершение процессов и потоков
Обработчики завершения не выполняются, если выполнение процесса или потока было прекращено независимо от того, было ли это инициировано самим процессом путем использования функций ExitProcess или ExitThread, или вызвано извне, например, инициировано вызовом функций TerminateProcess или TerminateThread из другого места в программе. Поэтому ни одна из этих функций не должна вызываться процессом или потоком внутри блоков try…except или try…finally.
Обратите также внимание, что выполнение функции библиотеки С exit или возврат из функции main приводят к выходу из процесса.
Читайте также
Обработчики завершения
Обработчики завершения Обработчики завершения служат в основном тем же целям, что и обработчики исключений, но выполняются, когда поток покидает блок в результате нормального выполнения программы, а также когда возникает исключение. С другой стороны, обработчик
Приоритеты процессов и потоков и планирование выполнения
Приоритеты процессов и потоков и планирование выполнения Ядро Windows всегда запускает тот из потоков, готовых к выполнению, который обладает наивысшим приоритетом. Поток не является готовым к выполнению, если он находится в состоянии ожидания, приостановлен или
Предостережение относительно использования приоритетов потоков и процессов
Предостережение относительно использования приоритетов потоков и процессов Высокими приоритетами потоков и высокими классами приоритета процессов необходимо пользоваться с осторожностью. Следует решительно избегать использования приоритетов реального времени для
Стеки потоков и допустимые количества потоков
Стеки потоков и допустимые количества потоков Следует сделать еще два предостережения. Во-первых, подумайте о размере стека, который по умолчанию составляет 1 Мбайт. В большинстве случаев этого будет вполне достаточно, но если существуют какие-либо сомнения на сей счет,
Обработчики прерываний
Обработчики прерываний Функция, которую выполняет ядро в ответ на определенное прерывание, называется обработчиком прерывания (interrupt handler) или подпрограммой обслуживания прерывания (interrupt service routine). Каждому устройству, которое генерирует прерывания, соответствует свой
Функции-обработчики
Функции-обработчики Не все вызовы обработчиков соответствуют клиентским сообщениям. Некоторые из них синтезируются ядром, а некоторые — библиотекой.Я организовал этот раздел следующим образом:• общие замечания;• замечания о функциях установления
Обработчики прерываний
Обработчики прерываний Обработчики прерываний в QNX4 могли либо возвратить идентификатор прокси (указывая этим, что надо переключить прокси и таким образом уведомить ее владельца о прерывании), либо возвратить нуль (что означало бы, что в дальнейшем ничего делать не
26.2. Основные функции для работы с потоками: создание и завершение потоков
26.2. Основные функции для работы с потоками: создание и завершение потоков В этом разделе мы рассматриваем пять основных функций для работы с потоками, а в следующих двух разделах мы используем эти функции для написания потоковой модификации клиента и сервера
1.1.9. Обработчики событий
1.1.9. Обработчики событий Обработчики события методы объекта. Это означает, что они должны быть методами класса, а не обычной процедурой или функцией (первый параметр должен быть Self). Для наиболее употребимых обработчиков предназначен следующий тип:TNotifyEvent = procedure(sender: TObject)
Обработчики прерываний
Обработчики прерываний Везде, кроме последней главы, все, что мы пока делали в ядре, сводилось к запросам и ответам разным процессам или работали со специальными файлом, посылали ioctl или выдавали системный вызов. Но работа ядра не должна сводится только к обработке
Взаимосвязь процессов, доменов приложений, контекстов и потоков
Взаимосвязь процессов, доменов приложений, контекстов и потоков В предыдущей главе обсуждалось понятие потока, который был определен, как путь исполнения в рамках выполняемого приложения. И хотя многие приложения .NET имеют только один поток и, тем не менее, оказываются
4.3.1. Обработчики очистки
4.3.1. Обработчики очистки Функции очистки ключей гарантируют, что в случае завершения или отмены потока не произойдет потерн ресурсов. Но иногда возникает необходимость в создании функции, которая будет связана не с ключом, дублируемым между потоками, а с обычным
4.6. Сравнение процессов и потоков
4.6. Сравнение процессов и потоков В некоторых программах, связанных с параллельным выполнением операций, сделать выбор в пользу процессов или потоков может оказаться достаточно сложно. Приведем рад правил, которые помогут читателям выбрать наилучшую модель для своих
Глава 6. Завершение и код завершения
Глава 6. Завершение и код завершения . эта часть Bourne shell покрыта мраком, тем не менее все пользуются ею. Chet RameyКоманда exit может использоваться для завершения работы сценария, точно так же как и в программах на языке C. Кроме того, она может возвращать некоторое значение,
Завершение и прекращение выполнения процесса
Завершение и прекращение выполнения процесса
После того как процесс завершил свою работу, он, или, точнее, выполняющийся в этом процессе поток, может вызвать функцию ExitProcess, указав в качестве параметра кодом завершения (exit code):
VOID ExitProcess(UINT uExitCode)
Эта функция не осуществляет возврата. Вместо этого она завершает вызывающий процесс и все его потоки. Обработчики завершения игнорируются, но делаются все необходимые вызовы точек входа DllMain (см. главу 5) с кодом отключения от библиотеки. Код завершения связывается с процессом. Выполнение оператора return в основной программе с использованием кода возврата равносильно вызову функции ExitProcess, в котором этот код возврата указан в качестве кода завершения.
Другой процесс может определить код завершения, вызвав функцию GetExitCodeProcess:
BOOL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode)
Процесс, идентифицируемый дескриптором hProcess, должен обладать правами доступа PROCESS_QUERY_INFORMATION (см. описание функции OpenProcess, которая нами уже обсуждалась). lpExitCode указывает на переменную типа DWORD, которая принимает значение кода завершения. Одним из ее возможных значений является STILL_ACTIVE, означающее, что данный процесс еще не завершился.
Наконец, один процесс может прекратить выполнение другого процесса, если у дескриптора завершаемого процесса имеются права доступа PROCESS_TERMINATE. При вызове функции завершения процесса указывается код завершения.
BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode)
Предостережение
Прежде чем завершить выполнение процесса, убедитесь в том, что все ресурсы, которые он мог разделять с другими процессами, освобождены. В частности, должны быть корректно обработаны ресурсы синхронизации, о которых говорится в главе 8 (мьютексы, семафоры и события). В этом отношении могут оказаться полезными SEH (глава 4), а вызов функции ExitProcess может быть осуществлен из обработчика. В то же время, при вызове функции ExitProcess обработчики __finally и __except не выполняются, поэтому в идее завершения выполнения изнутри программы нет ничего хорошего. Особенно рискованно применять функцию TerminateProcess, поскольку у завершаемого процесса в этом случае отсутствует возможность выполнить свои SEH или вызвать функции DllMain связанных с ним библиотек DLL. Ограниченной альтернативой являются обработчики управляющих сигналов консоли, обеспечивающие возможность передачи сигнала одним процессом другому, который после этого может корректно организовать свое завершение.
Программа 6.3 иллюстрирует применение методики, обеспечивающей взаимодействие между процессами. В этом примере один процесс посылает другому процессу запрос завершения выполнения, получив который второй процесс сможет аккуратно завершить свою работу.
Процессы UNIX имеют свои идентификаторы, pid, которые сопоставимы с идентификаторами процессов Windows. Функция getpid аналогична функции GetCurrentProcessID, но эквивалентов функциям getppid и getgpid в Windows не находится ввиду отсутствия предков процессов и групп процессов.
И, наоборот, в UNIX отсутствуют дескрипторы процессов, и поэтому в ней нет функций, которые можно было бы сравнить с функциями GetCurrentProcess или OpenProcess.
В UNIX допускается использование дескрипторов (descriptors) открытых файлов после вызова функции exec, если для дескриптора файла не был установлен флаг close-on-exec. Это правило применимо только к дескрипторам файлов, которые, в силу вышесказанного, можно сравнить с наследуемыми дескрипторами (handles) файлов Windows.
Функция UNIX exit, которая фактически является функцией библиотеки С, аналогична функции ExitProcess; чтобы прекратить выполнение другого процесса ему следует послать сигнал SIGKILL.
Читайте также
9.1.5. Завершение процесса
9.1.5. Завершение процесса Завершение процесса включает два шага: окончание процесса с передачей системе статуса завершения и восстановление информации родительским
Завершение процесса
Завершение процесса Как это ни грустно, но любой процесс в конечном итоге должен завершиться. Когда процесс завершается, ядро должно освободить ресурсы, занятые процессом, и оповестить процесс, который является родительским для завершившегося, о том, что его порожденный
Завершение процесса
Завершение процесса С завершением процесса дело обстоит достаточно просто, по крайней мере, в сравнении с тем, что происходит при завершении потока, как это и будет показано очень скоро. Процесс завершается, если программа выполняет вызов exit() или выполнение просто
Завершение выполнения процесса
Завершение выполнения процесса Процесс завершает свое выполнение с помощью функции exit(). Эта функция может быть вызвана системным вызовом exit(2), а если завершение процесса вызвано получением сигнала, функцию exit() вызывает само ядро. Функция exit() выполняет следующие
5.12. Завершение процесса сервера
5.12. Завершение процесса сервера Теперь мы запустим соединение клиент-сервер и уничтожим дочерний процесс сервера. Это симулирует сбой процесса сервера, благодаря чему мы сможем выяснить, что происходит с клиентом в подобных ситуациях. (Следует точно различать сбой
7.4 ОЖИДАНИЕ ЗАВЕРШЕНИЯ ВЫПОЛНЕНИЯ ПРОЦЕССА
7.4 ОЖИДАНИЕ ЗАВЕРШЕНИЯ ВЫПОЛНЕНИЯ ПРОЦЕССА Процесс может синхронизировать продолжение своего выполнения с моментом завершения потомка, если воспользуется системной функцией wait. Синтаксис вызова функции:pid = wait(stat_addr);где pid — значение кода идентификации (PID)
Создание, завершение и просмотр учетной записи процесса
Создание, завершение и просмотр учетной записи процесса К другим основным возможностям инструментария управления WMI относятся возможности работы с процессами, запущенными на удаленном или локальном компьютере. При этом инструментарий предоставляет возможности не
7.3.2. Концепции, касающиеся основных средств производственного процесса организации Основные средства производственного процесса организации (ППО)
7.3.2. Концепции, касающиеся основных средств производственного процесса организации Основные средства производственного процесса организации (ППО) Организация устанавливает и сопровождает набор основных средств производственного процесса, как показано на рис. 4.1. К
Завершение процесса, заблокировавшего ресурс
Завершение процесса, заблокировавшего ресурс Когда взаимное исключение используется совместно несколькими процессами, всегда существует возможность, что процесс будет завершен (возможно, принудительно) во время работы с заблокированным им ресурсом. Не существует
Завершение процесса с помощью команды KILL
Завершение процесса с помощью команды KILL В SQL Server администратор может удалить процесс, например пользовательское подключение или блокировку базы данных, с помощью команды KILL. Обычно эта команда применяется для чрезвычайного прекращения пользовательского сеанса,
В завершение
В завершение Тестированию, которое мы знаем и любим, приходит конец. Кого-то эта новость огорчит. Тем, чья карьера зависит от текущей схемы работы, придется намного сложнее. Так или иначе, разработка программного обеспечения фундаментально изменилась с приходом гибких
3.4. Завершение процесса
3.4. Завершение процесса Обычно процесс завершается одним из двух способов: либо выполняющаяся программа вызывает функцию exit(), либо функция main() заканчивается. У каждого процесса есть код завершения — число, возвращаемое родительскому процессу. Этот код передается в
18.8.2. Прекращение выполнения оператора case
18.8.2. Прекращение выполнения оператора case Рассмотрим следующий пример. В сценарии выполняется бесконечный цикл до тех пор, пока пользователь не введет число, большее 5. Для прерывания цикла и возврата в командную строку интерпретатора используется команда break.$ pg
Завершение
Завершение Если все списки САС проанализированы, а переменная состояния маски причины не показывает, что все причины аннулирования проверены, то переменная состояния статуса сертификата принимает значение «не определен». Большинство приложений будет реагировать на