запускать внешнюю программу в цикле с максимальным ограничением времени

1

Я хочу иметь python script, который последовательно запускает внешнюю программу в цикле. Я также хочу ограничить каждое выполнение программы максимальным временем выполнения. Если он превышен, то убить программу. Каков наилучший способ сделать это?

Спасибо!

  • 2
    Здесь нет вопроса. Вы также не показали никакой работы в этом. Покажите код и перефразируйте, пожалуйста.
  • 0
    "Каков наилучший способ сделать это?" <- Похоже на вопрос для меня.
Показать ещё 1 комментарий
Теги:

2 ответа

4

Чтобы запустить внешнюю программу с Python, вы обычно захотите использовать модуль подпроцесса .

С помощью os.fork() и os.execve() (или одного из его двоюродных братьев exec*) вы можете "сворачивать свою собственную" обработку подпроцесса... с любым файловым дескриптором сантехники и обработкой сигналов, которые вам нравятся. Однако функция subprocess.Popen() реализовала и раскрыла большинство функций для того, что вы хотели бы сделать для вас.

Чтобы программа могла умереть через определенный промежуток времени, вы можете заставить свой Python script убить его после таймаута. Естественно, вы захотите проверить, завершен ли процесс до этого. Здесь глупый пример грязи (с помощью функции split от shlex module для дополнительной читаемости:

from shlex import split as splitsh
import subprocess
import time

TIMEOUT=10
cmd = splitsh('/usr/bin/sleep 60')
proc = subprocess.Popen(cmd)
time.sleep(TIMEOUT)
pstatus = proc.poll()
if pstatus is None:
    proc.kill()
# Could use os.kill() to send a specific signal
# such as HUP or TERM, check status again and 
# then resort to proc.kill() or os.kill() for
# SIGKILL only if necessary

Как уже отмечалось, есть несколько способов убить ваш подпроцесс. Обратите внимание, что я проверяю "is None" вместо проверки pstatus для правды. Если ваш процесс завершен с нулевым значением выхода (условно указывающим на отсутствие ошибки), то наивный тест результатов proc.poll() будет конфликтовать это завершение с еще неработающим статусом процесса.

Существует также несколько способов определить, прошло ли достаточно времени. В этом примере мы спим, что несколько глупо, если что-то еще мы можем сделать. Это просто оставляет наш процесс Python (родительский компонент вашей внешней программы), лежащий около простоя.

Вы можете записать время начала с помощью time.time(), затем запустить свой подпроцесс, затем выполнить другую работу (например, запустить другие подпроцессы) и проверить время (возможно, в цикле другой активности) до тех пор, пока не будет превышен желаемый тайм-аут.

Если какое-либо из ваших действий связано с файловыми или сокетными (сетевыми) операциями, вы должны рассмотреть возможность использования выбрать модуль в качестве способ вернуть список дескрипторов файлов, которые можно читать, записывать или готовить с "исключительными" событиями. Функция select.select() также принимает необязательное значение "timeout". Вызов select.select([],[],[],x) по существу такой же, как time.sleep(x) (в случае, если мы не предоставляем никаких файловых дескрипторов для его выбора).

Вместо select.select() также можно использовать модуль fcntl, чтобы установить дескриптор файла в неблокирующий режим а затем используйте os.read() (НЕ обычный метод .read()), но функциональность более низкого уровня из os module). Опять же, лучше использовать интерфейсы более высокого уровня, где это возможно, и только прибегать к функциям более низкого уровня, когда вы должны. (Если вы используете неблокирующий ввод-вывод, то все ваши os.read() или подобные операции должны выполняться в блоках обработки исключений, поскольку Python будет представлять условие "-EWOULDBLOCK" как OSError (исключение), например: "OSError: [Errno 11] Ресурс временно недоступен" (Linux). Точное число ошибок может варьироваться от одной ОС к другой. Однако оно должно быть переносимым (по крайней мере для систем POSIX) для использования значения -EWOULDBLOCK из модуль errno.

(Я понимаю, что я собираюсь спуститься сюда, но информация о том, как ваша программа может сделать что-то полезное, в то время как ваши дочерние процессы запускают внешние программы, является естественным расширением того, как управлять таймаутами для них).

В прошлом обсуждались подробности о неблокирующих вводах файлов (включая проблемы с переносимостью в MS Windows): qaru.site/questions/1662/...

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

1

Если вы можете использовать Python 3.3

Из docs,

subprocess.call(args, *, stdin = None, stdout = None, stderr = None, shell = False, таймаут= Нет)

  

subprocess.call([ "ls", "-l" ])     0

         

subprocess.call( "exit 1", shell = True)     1

  

Должен сделать трюк.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню