Какой лучший подход для ограничения времени, в течение которого функция может выполняться? - PullRequest
4 голосов
/ 17 апреля 2019

Я создал инструмент, использующий django для автоматизации выполнения скриптов.Инструмент работает нормально, но иногда выполнение сценариев занимает слишком много времени.Я хочу ограничить время, в течение которого мой инструмент может выполнять каждый скрипт.Я нашел 2 подхода и реализовал их, но я не уверен, какой из них правильный.

1.) Использование сигнального модуля
2.) Использование многопроцессорной обработки

ВотПример кода для обоих подходов

1.) Использование сигнального модуля

import signal
from contextlib import contextmanager

class TimeoutException(Exception): pass

@contextmanager
def time_limit(seconds):
    def signal_handler(signum, frame):
        raise TimeoutException("Timed out!")
    signal.signal(signal.SIGALRM, signal_handler)
    signal.alarm(seconds)
    try:
        yield
    finally:
        signal.alarm(0)

try:
    with time_limit(10):
        long_function_call()
except TimeoutException as e:
    print("Timed out!")

2.) Использование многопроцессорной обработки

from multiprocessing import Process
from time import sleep

def f(time):
    sleep(time)

def run_with_limited_time(func, args, kwargs, time):
    p = Process(target=func, args=args, kwargs=kwargs)
    p.start()
    p.join(time)
    if p.is_alive():
        p.terminate()
        return False

    return True

if __name__ == '__main__':
    print run_with_limited_time(f, (1.5, ), {}, 2.5) # True
    print run_with_limited_time(f, (3.5, ), {}, 2.5) # False

Проблема, с которой сталкивается сигнальный модуль:этот сигнал работает только в основном потоке.Хотите знать, какой подход лучше и почему?Также, если есть какой-либо подход, я могу использовать, чтобы изменить поведение сигнального модуля.

1 Ответ

2 голосов
/ 17 апреля 2019

Подход, основанный на сигнале, имеет несколько угловых случаев и ограничений.Он не является переносимым, сигналы могут обрабатываться только в основном потоке, и если ваше приложение занято в низкоуровневой петле (например, из-за вызова некоторого API C), ваше приложение перестает отвечать на запросы.

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

Создано несколько библиотекза помощь в этом мне на ум приходят галька и бильярд .

...