Python 3 завершить процесс windows

Обновлено: 07.07.2024

Я написал программу на IDLE для токенизации текстовых файлов, и она начинает токенизировать 349 текстовых файлов! Как мне это остановить? Как я могу остановить работающую программу Python?

Многие ответы здесь зависят от платформы. Найдите свою платформу (Windows, Linux, Mac, что-нибудь еще?)

Чтобы остановить вашу программу, просто нажмите Control + C .

Этот метод работал на моем ноутбуке с Windows, но на моем рабочем столе Linux он отображался ^C в терминале, а системный монитор показал, что python все еще использует много ЦП . @Gathide Если вы хотите приостановить процесс и перевести его в фоновый режим, нажмите Ctrl + Z (по крайней мере, в Linux). Затем, если вы хотите убить его, запустите, kill %n где «n» - это число, которое вы получили рядом с «Остановлено» при нажатии Ctrl + Z . Если хотите его возобновить, бегите fg . Не работает, если в программе есть общее предложение except :. Исключение: перехватывает прерывание, что-то делает (или нет), а затем программа весело продолжает работу.

Вы также можете сделать это, если используете exit() функцию в своем коде. В идеале можно sys.exit() . sys.exit() что может завершить работу Python, даже если вы запускаете что-то параллельно через multiprocessing пакет.

Примечание: чтобы использовать sys.exit() , вы должны импортировать его: import sys

Примечание: я мог найти примеры, в которых sys.exit(1) не останавливается процесс. У меня в основном несколько потоков, и каждый из них блокирует внешние процессы, запущенные Popen . Мне нужен ядерный вариант, чтобы убить все подпроцессы, созданные процессом Python, а также сам процесс Python. Пока не нашел. sys.exit () не убивает процесс, но вызывает исключение SystemExit Exception, которое не останавливает выполнение, закрывая программу

Если ваша программа запущена на интерактивной консоли, нажатие CTRL + C вызовет KeyboardInterrupt исключение в основном потоке.

Если ваша программа Python его не поймает, KeyboardInterrupt Python завершится. Однако except KeyboardInterrupt: блок или что-то вроде голого except: не позволят этому механизму фактически остановить запуск скрипта.

Однако эти механизмы в основном работают, только если интерпретатор Python работает и реагирует на события операционной системы. Если интерпретатор Python по какой-либо причине не отвечает, наиболее эффективным способом является завершение всего процесса операционной системы, в котором запущен интерпретатор. Механизм этого зависит от операционной системы.

В среде оболочки в стиле Unix вы можете нажать CTRL +, Z чтобы приостановить любой процесс, который в настоящее время управляет консолью. После того, как вы получите приглашение оболочки, вы можете использовать его jobs для вывода списка приостановленных заданий, и вы можете убить первое приостановленное задание с помощью kill %1 . (Если вы хотите запустить его снова, вы можете продолжить работу на переднем плане, используя fg %1 ; прочтите руководство вашей оболочки по управлению заданиями для получения дополнительной информации.)

В качестве альтернативы, в Unix или Unix-подобной среде вы можете найти PID процесса Python (идентификатор процесса) и убить его с помощью PID. Используйте что-то вроде того, ps aux | grep python чтобы найти, какие процессы Python запущены, а затем использовать kill <pid> для отправки SIGTERM сигнала.

Команда kill в Unix отправляется SIGTERM по умолчанию, и программа Python может установить обработчик сигнала для SIGTERM использования signal модуля. Теоретически любой обработчик сигналов SIGTERM должен корректно завершать процесс. Но иногда, если процесс застревает (например, заблокирован в состоянии непрерывного сна ввода-вывода), SIGTERM сигнал не имеет никакого эффекта, потому что процесс даже не может проснуться, чтобы обработать его.

Как сделать раннее завершение программы в Python? В самоучителе я нашёл несколько примеров:

Однако там не было объяснения какой метод лучше. Какой метод является наиболее "безаварийным"?

И заодно: есть ли в Python понятие Autocloseable объектов? Если я сделаю ранее завершение программы, нужно ли мне будет закрывать файлы и т.д.?

1,267 2 2 золотых знака 16 16 серебряных знаков 30 30 бронзовых знаков Спасибо! Лучшим решением является использование sys.exit() на счет второго: лучше закрывать/завершать все операции перед завершением программы

Короткий ответ:
Лучше использовать sys.exit()

Механизм завершения процесса в Python реализован через бросание исключения SystemExit , таким образом можно просто создать подобное исключение и программа завершится:

Функция exit и аналогичная ей quit созданы для удобства работы в интерактивном режиме и их не рекомендуется использовать внутри скриптов:

They are useful for the interactive interpreter shell and should not be used in programs.

По факту они также просто поднимают исключение, и при попытке вызова без скобок напишут подсказку о правильном способе выхода из интерпретатора:

Использовать sys.exit стоит потому, что эта функция лежит в стандартном модуле и будет всегда там доступна. Также это довольно явный способ выразить своё желание завершить программу.

Есть также дополнительный метод для немедленного завершения программы: os._exit . У него довольно специфическая область применения, и там же есть замечание:

The standard way to exit is sys.exit(n)

Т.е. здесь даётся подтверждение того, что стандартный способ завершения программы -- это вызов sys.exit .

Функция os.abort , упомянутая вами, использует механизм сигналов процессу. Конкретно при вызове этой функции будет передан сигнал SIGABRT , что в linux приведёт к завершению программы и созданию дампа памяти процесса. Подобное завершение рассматривается операционной системой как аварийное, поэтому не стоит использовать его для безаварийного завершения приложения.

По второй части вопроса. В Python есть развитая система контекстных менеджеров: классов, которые умеют работать с оператором with . Самое частое использование этого механизма встречается, вероятно, с файлами.

Этот код откроет файл, напечатает его содержимое на экран и закроет файл автоматически, даже если возникнет исключение при его печати.

Для классов, которые не приспособлены для работы с with есть функция closing в библиотеке contextlib . Из документации:

Code like this:

is equivalent to this:

Вот небольшой пример работы этой функции:

Теперь небольшое отступление о том, почему стоит использовать конструкцию with .

Известно, что программа завершится от любого необработанного исключения, а не только от SystemExit . Таким образом, если в вашем коде используются какие-то ресурсы, которые требуется правильным образом закрывать перед завершением работы, нужно оборачивать работу с ними в блоки try . finally . .

Однако, при использовании конструкции with это оборачивание происходит автоматически, и все ресурсы закрываются корректно.

Так как выход из программы -- это всего лишь брошенное исключение, то и в случае использования функции sys.exit закрытие открытых в операторе with ресурсов произойдёт корректно:

Вы можете писать также и свои классы, предоставляющие ресурсы или классы, оборачивающие другие, которые нужно уметь закрывать автоматически. Для этого используются методы __enter__ и __exit__ .

Я написал сценарий Python, который должен в конечном итоге выключить компьютер.

Эта строка является ее частью:

Это делает своего рода выключение, но остается на включенной панели управления Windows (где пользователь может переключать пользователей компьютера).

Есть ли способ полностью выключить компьютер?

Я пробовал другие методы os.system("shutdown ___") безуспешно.

Есть ли другой метод, который может помочь?

Это будет работать для вас.

или: если вы хотите немедленное отключение без Sudo Запрашивать пароль, используйте следующее для Ubuntu и подобных дистрибутивов:

Используя ctypes вы можете использовать функцию ExitWindowsEx для выключения компьютера.

Описание из MSDN:

Выход из системы интерактивного пользователя, выключение системы или выключение и перезагрузка системы.

Сначала немного кода:

Теперь объяснение построчно:

  • Получить библиотеку ctypes
  • ExitWindowsEx предоставляется user32.dll и должен быть загружен через WinDLL()
  • Вызовите функцию ExitWindowsEx() и передайте необходимые параметры.

Параметры:

Все аргументы шестнадцатеричные.

Первый выбранный мной аргумент:

выключает систему и выключает питание. Система должна поддерживать функцию отключения питания.

Есть много других возможных функций, см. документацию для полного списка.

Второй аргумент must указывает причину отключения, которая регистрируется системой. В этом случае я установил для Other issue , но есть из чего выбирать. Смотрите это для полного списка.

Создание кроссплатформенности:

Это может быть объединено с другими методами, чтобы сделать его кроссплатформенным. Например:

Это зависимая от Windows функция (хотя Linux/Mac будет иметь эквивалент), но это лучшее решение, чем вызов os.system() , поскольку пакетный скрипт с именем shutdown.bat не будет конфликтовать с командой (и тем временем вызывать угрозу безопасности) .

В качестве примечания: Я собрал WinUtils (только для Windows), что немного упрощает это, однако он должен быть быстрее (и не требует Ctypes), поскольку он встроен в C.

В скриптах, написанных для автоматизации определенных задач, нам часто требуется запускать внешние программы и контролировать их выполнение. При работе с Python мы можем использовать модуль subprocess для создания подобных скриптов. Этот модуль является частью стандартной библиотеки языка. В данном руководстве мы кратко рассмотрим subprocess и изучим основы его использования.

Прочитав статью, вы узнаете как:

  • Использовать функцию run для запуска внешнего процесса.
  • Получить стандартный вывод процесса и информацию об ошибках.
  • Проверить код возврата процесса и вызвать исключение в случае сбоя.
  • Запустить процесс, используя оболочку в качестве посредника.
  • Установить время ожидания завершения процесса.
  • Использовать класс Popen напрямую для создания конвейера ( pipe ) между двумя процессами.

Так как модуль subprocess почти всегда используют с Linux все примеры будут касаться Ubuntu. Для пользователей Windows советую скачать терминал Ubuntu 18.04 LTS.

Функция «run»

Функция run была добавлена в модуль subprocess только в относительно последних версиях Python (3.5). Теперь ее использование является рекомендуемым способом создания процессов и должно решать наиболее распространенные задачи. Прежде всего, давайте посмотрим на простейший случай применения функции run .

Предположим, мы хотим запустить команду ls -al ; для этого в оболочке Python нам нужно ввести следующие инструкции:

Вывод внешней команды ls отображается на экране:

Здесь мы просто использовали первый обязательный аргумент функции run , который может быть последовательностью, «описывающей» команду и ее аргументы (как в примере), или строкой, которая должна использоваться при запуске с аргументом shell=True (мы рассмотрим последний случай позже).

Захват вывода команды: stdout и stderr

Что, если мы не хотим, чтобы вывод процесса отображался на экране. Вместо этого, нужно чтобы он сохранялся: на него можно было ссылаться после выхода из процесса? В этом случае нам стоит установить для аргумента функции capture_output значение True :

Как мы можем впоследствии получить вывод ( stdout и stderr ) процесса? Если вы посмотрите на приведенные выше примеры, то увидите, что мы использовали переменную process для ссылки на объект CompletedProcess , возвращаемый функцией run . Этот объект представляет процесс, запущенный функцией, и имеет много полезных свойств. Помимо прочих, stdout и stderr используются для «хранения» соответствующих дескрипторов команды, если, как уже было сказано, для аргумента capture_output установлено значение True . В этом случае, чтобы получить stdout , мы должны использовать:

По умолчанию stdout и stderr представляют собой последовательности байтов. Если мы хотим, чтобы они хранились в виде строк, мы должны установить для аргумента text функции run значение True .

Управление сбоями процесса

Команда, которую мы запускали в предыдущих примерах, была выполнена без ошибок. Однако при написании программы следует принимать во внимание все случаи. Так, что случится, если порожденный процесс даст сбой? По умолчанию ничего «особенного» не происходит. Давайте посмотрим на примере: мы снова запускаем команду ls , пытаясь вывести список содержимого каталога /root, который не доступен для чтения обычным пользователям:

Мы можем узнать, не завершился ли запущенный процесс ошибкой, проверив его код возврата, который хранится в свойстве returncode объекта CompletedProcess :

Видите? В этом случае returncode равен 2 , подтверждая, что процесс столкнулся с ошибкой, связанной с недостаточными правами доступа, и не был успешно завершен. Мы могли бы проверять выходные данные процесса таким образом чтобы при возникновении сбоя возникало исключение. Используйте аргумент check функции run : если для него установлено значение True , то в случае, когда внешний процесс завершается ошибкой, возникает исключение CalledProcessError :

Обработка исключений в Python довольно проста. Поэтому для управления сбоями процесса мы могли бы написать что-то вроде:

Исключение CalledProcessError , как мы уже сказали, возникает, когда код возврата процесса не является 0 . У данного объекта есть такие свойства, как returncode , cmd , stdout , stderr ; то, что они представляют, довольно очевидно. Например, в приведенном выше примере мы просто использовали свойство cmd , чтобы отобразить последовательность, которая использовалась для запуска команды при возникновении исключения.

Выполнение процесса в оболочке

Процессы, запущенные с помощью функции run , выполняются «напрямую», это означает, что для их запуска не используется оболочка: поэтому для процесса не доступны никакие переменные среды и не выполняются раскрытие и подстановка выражений. Давайте посмотрим на пример, который включает использование переменной $HOME :

Как видите, переменная $HOME не была заменена на соответствующее значение. Такой способ выполнения процессов является рекомендованным, так как позволяет избежать потенциальные угрозы безопасности. Однако, в некоторых случаях, когда нам нужно вызвать оболочку в качестве промежуточного процесса, достаточно установить для параметра shell функции run значение True . В таких случаях желательно указать команду и ее аргументы в виде строки:

Все переменные, существующие в пользовательской среде, могут использоваться при вызове оболочки в качестве промежуточного процесса. Хотя это может показаться удобным, такой подход является источником проблем. Особенно при работе с потенциально опасным вводом, который может привести к внедрению вредоносного shell-кода. Поэтому запуск процесса с shell=True не рекомендуется и должен использоваться только в безопасных случаях.

Ограничение времени работы процесса

Обычно мы не хотим, чтобы некорректно работающие процессы бесконечно исполнялись в нашей системе после их запуска. Если мы используем параметр timeout функции run , то можем указать количество времени в секундах, в течение которого процесс должен завершиться. Если он не будет завершен за это время, процесс будет остановлен сигналом SIGKILL. Который, как мы знаем, не может быть перехвачен. Давайте продемонстрируем это, запустив длительный процесс и предоставив timeout в секундах:

В приведенном выше примере мы запустили команду ping без указания фиксированного числа пакетов ECHO REQUEST, поэтому она потенциально может работать вечно. Мы также установили время ожидания в 5 секунд с помощью параметра timeout . Как мы видим, ping была запущена, а по истечении 5 секунд возникло исключение TimeoutExpired и процесс был остановлен.

Функции call, check_output и check_call

Как мы уже говорили ранее, функция run является рекомендуемым способом запуска внешнего процесса. Она должна использоваться в большинстве случаев. До того, как она была представлена в Python 3.5, тремя основными функциями API высокого уровня, применяемыми для создания процессов, были call , check_output и check_call ; давайте взглянем на них вкратце.

Прежде всего, функция call : она используется для выполнения команды, описанной параметром args; она ожидает завершения команды; ее результатом является соответствующий код возврата. Это примерно соответствует базовому использованию функции run.

Поведение функции check_call практически не отличается от run , когда для параметра check задано значение True : она запускает указанную команду и ожидает ее завершения. Если код возврата не равен 0 , возникает исключение CalledProcessError .

Наконец, функция check_output . Она работает аналогично check_call , но возвращает вывод запущенной программы, то есть он не отображается при выполнении функции.

Работа на более низком уровне с классом Popen

До сих пор мы изучали функции API высокого уровня в модуле subprocess, особенно run . Все они под капотом используют класс Popen . Из-за этого в подавляющем большинстве случаев нам не нужно взаимодействовать с ним напрямую. Однако, когда требуется большая гибкость, без создания объектов Popen не обойтись.

Предположим, например, что мы хотим соединить два процесса, воссоздав поведение конвейера (pipe) оболочки. Как мы знаем, когда передаем две команды в оболочку, стандартный вывод той, что находится слева от пайпа «|», используется как стандартный ввод той, которая находится справа. В приведенном ниже примере результат выполнения двух связанных конвейером команд сохраняется в переменной:

Чтобы воссоздать подобное поведение с помощью модуля subprocess без установки параметра shell в значение True , как мы видели ранее, мы должны напрямую использовать класс Popen :

Читайте также: