Python超时装饰器

Python超时装饰器,第1张

Python超时装饰器

这是

signal
您链接的装饰器使用的模块计时功能的限制。这是文档的相关部分(我重点强调):

signal.alarm(time)

如果时间不为零,则此函数要求

SIGALRM
time
秒为单位将信号发送到进程。
任何先前计划的警报都会被取消(任何时候都只能计划一个警报)。
然后,返回值是在传递任何先前设置的警报之前的秒数。如果
time
为零,则不计划任何警报,并且任何计划的警报都将被取消。如果返回值为零,则当前未计划任何警报。(请参见Unix手册页alarm(2)。)可用性:Unix。

因此,您所看到的是,在

nested_func
调用your时,它的计时器取消了外部函数的计时器。

您可以更新装饰器,以注意

alarm
呼叫的返回值(这是上一个警报(如果有)到期之前的时间)。正确获取细节有点复杂,因为内部计时器需要跟踪其功能运行了多长时间,因此它可以修改前一个计时器上的剩余时间。这是装饰器的一个未经测试的版本,我认为它基本上是正确的(但是我不完全确定它对于所有异常情况都可以正常工作):

import timeimport signalclass TimeoutError(Exception):    def __init__(self, value = "Timed Out"):        self.value = value    def __str__(self):        return repr(self.value)def timeout(seconds_before_timeout):    def decorate(f):        def handler(signum, frame): raise TimeoutError()        def new_f(*args, **kwargs): old = signal.signal(signal.SIGALRM, handler) old_time_left = signal.alarm(seconds_before_timeout) if 0 < old_time_left < second_before_timeout: # never lengthen existing timer     signal.alarm(old_time_left) start_time = time.time() try:     result = f(*args, **kwargs) finally:     if old_time_left > 0: # deduct f's run time from the saved timer         old_time_left -= time.time() - start_time     signal.signal(signal.SIGALRM, old)     signal.alarm(old_time_left) return result        new_f.func_name = f.func_name        return new_f    return decorate


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5601885.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-15
下一篇2022-12-15

发表评论

登录后才能评论

评论列表(0条)

    保存