Страницы

Поиск по вопросам

понедельник, 27 мая 2019 г.

Прерывание процесса и задержка на исполнение

Подскажите, как осуществить прерывание системного процесса на Винде из питона? Допустим, код выполняется до определенного момента, затем винда запускает внешний процесс, который надо остановить и лишь потом продолжить выполнение кода. Так же интересует вопрос, как добавить задержку перед выполнением следующего блока кода?


Ответ

Чтобы прервать внешнюю команду через заданный промежуток времени, можно передать timeout параметр при её запуске:
import subprocess
subprocess.check_call(command, timeout=timeout)
Если command не завершится через timeout секунд, то соответствующий процесс убивается и выбрасывается subprocess.TimeoutExpired исключение. Иногда этого не достаточно и необходимо руками убить всё дерево процессов, особенно если вы читаете вывод внешней команды. Вот пример кода, поддерживающий старые версии Питона (Python 2), который показывает как остановить "вечную" внешнюю команду через пару секунд, накапливая её вывод пока она выполняется. Если вы не хотите блокировать основной поток на время выполнения команды, то существует множество способов взаимодействия с командой асинхронно, чтобы найти примеры кода для разных случаев, следуйте по ссылкам
Если команда запущена вне Питона и вы хотите убить её через заданное время по имени:
process = get_process_by_name(name) try: process.wait(timeout) except TimeoutExpired: process.kill() process.wait()
.wait() завершается, если процесс вышел или время истекло—что раньше. Это очень близко к тому как subprocess.call() реализован
Существует множество других способов отложить запуск функции в Питоне, например, чтобы запустить функцию через timeout секунд, не блокируя основной поток всё это время:
import threading
threading.Timer(timeout, kill_process_by_name, [name]).start()
ещё: time.sleep(timeout) или time.sleep(interval - timer() % interval), или Event.wait(timeout), или используя методы из соответствующих циклов обработки событий (event loop)—что выбрать, зависит от конкретной задачи. В общем случае, чтобы прервать выполнение функции в Питоне, см. Timeout on a function call
Примеры реализаций как можно найти процесс по имени и убить его:
import psutil # $ pip install psutil
def get_process_by_name(name): for proc in psutil.process_iter(): try: if proc.name() == name: return proc except psutil.NoSuchProcess: continue raise KeyError("Process {name!r} not found".format(name=name))
def kill_process_by_name(name): get_process_by_name(name).kill()
def kill_process_tree_by_name_windows(name): subprocess.call(['taskkill', '/im', name, '/f', '/t'])

Комментариев нет:

Отправить комментарий