哪种方法可以更好地限制函数执行的时间?

时间:2019-04-17 06:58:33

标签: python multiprocessing signals

我已经使用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 个答案:

答案 0 :(得分:2)

基于信号的方法带有一些特殊情况和局限性。它不是可移植的,信号只能在主线程上处理,并且如果您的应用程序在低级循环中忙(例如,因为它正在调用某些C api),您的应用程序将变得无响应。

我建议使用基于multiprocessing的方法,因为它克服了上述所有限制并具有一个主要优点:它可以保护您的服务免于因函数中运行的逻辑而导致的崩溃,超时和不稳定性。

为此构建的库很少,pebblebilliard是我想到的库。