Выполнение лимитной функции в Python

Есть много похожих вопросов и ответов, но я до сих пор не могу найти надежный ответ.

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

Я хочу ограничить время его выполнения до 60 секунд. Я пробовал следующие подходы:

  1. Сигналы Python. Не работайте в Windows и многопоточном окружении (mod_wsgi).
  2. Потоки. Хороший способ, но поток не может быть остановлен, так что он живет даже после TimeoutException .
  3. multiprocessing модуль python. У меня проблемы с травлением, и я не знаю, как их решить. Я хочу создать декоратор time_limit, и есть проблемы с импортом требуемой функции на верхнем уровне. Функция, выполняемая long, является методом экземпляра, и ее перенос также не помогает …

Итак, есть ли хорошие решения этой проблемы? Как убить нить, что я начал? Как использовать подпроцессы и избегать проблем с травлением? subprocess модуль какой-либо помощи?

Спасибо.

2 Solutions collect form web for “Выполнение лимитной функции в Python”

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

 import multiprocessing import Queue def timed_function(return_queue): do_other_stuff() return_queue.put(True) return def main(): return_queue = multiprocessing.Manager().Queue() proc = multiprocessing.Process(target=timed_function, args=(return_queue,)) proc.start() try: # wait for 60 seconds for the function to return a value return_queue.get(timeout=60) except Queue.Empty: # timeout expired proc.terminate() # kill the subprocess # other cleanup - import multiprocessing import Queue def timed_function(return_queue): do_other_stuff() return_queue.put(True) return def main(): return_queue = multiprocessing.Manager().Queue() proc = multiprocessing.Process(target=timed_function, args=(return_queue,)) proc.start() try: # wait for 60 seconds for the function to return a value return_queue.get(timeout=60) except Queue.Empty: # timeout expired proc.terminate() # kill the subprocess # other cleanup 

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

 class TestClass(object): def timed_method(self, return_queue): do_other_stuff() return_queue.put(True) return 

Чтобы использовать этот метод в пуле рабочих, добавьте эту оболочку на верхний уровень модуля:

 def _timed_method_wrapper(TestClass_object, return_queue): return TestClass_object(return_queue) 

Теперь вы можете, например, использовать apply_async для этого метода класса из другого метода того же класса:

 def run_timed_method(): return_queue = multiprocessing.Manager().Queue() pool = multiprocessing.Pool() result = pool.apply_async(_timed_method_wrapper, args=(self, return_queue)) 

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

Ответ: Можно ли убить процесс в Windows из Python? может помочь: вам нужно убить этот подпроцесс или поток: «Завершение подпроцесса в окнах»

Возможно, также TerminateThread помогает

  • Scapy sniff () в классе, что подклассы threading.Thread ()
  • объект .__ новый __ (thread.lock) небезопасен, используйте thread.lock .__ new __ ()
  • Закрыть поток Python для предотвращения утечки памяти
  • Асинхронный интерактивный скрипт Python
  • Убейте функцию подвески в Python в многопоточном окружении
  • Хороший пример реализации многопроцессорности?
  • несколько потоков QWebView в PyQt4
  • Откладывание функций в python
  • Python - лучший язык программирования в мире.