Python的函数超时API

时间:2014-10-29 17:44:28

标签: python multithreading timeout

我正在尝试实现一个函数,如果它在一定时间内无法完成(在线程挂起时出现问题)将会超时。这个answer似乎是最有希望的,有效地提供了一个API包装器,用来调用我的实际功能。它通常似乎有效(请参阅loop_forever),但在使用time.sleep时无法停止。为什么超时不适用于睡眠定时器,这是否可以防止线程挂起?

import signal
import time

def timeout(func, args=(), kwargs={}, timeout_duration=1, default=None):


    class TimeoutError(Exception):
        pass

    def handler(signum, frame):
        raise TimeoutError()

    # set the timeout handler
    signal.signal(signal.SIGALRM, handler) 
    signal.alarm(timeout_duration)
    try:
        result = func(*args, **kwargs)
    except TimeoutError as exc:
        result = default
    finally:
        signal.alarm(0)

    return result




def loop_forever():
    x = 0
    while True:
        print x
        try:
            x += 1
        except:
            continue

def loop_forever_sleep():
    x = 0
    while True:
        print x
        try:
            x += 1
            time.sleep(10)
        except:
            continue

if __name__ == '__main__':
    a = timeout(loop_forever) #Terminates
    b = timeout(loop_forever_sleep) #Does not terminate

1 个答案:

答案 0 :(得分:1)

问题是SIGALRM系统调用时会引发time.sleep(10),这会导致您在该上下文中调用handler。但是,您正在吞噬无限循环内发生的所有异常,因此TimeoutError永远不会将其返回到timeout函数,而是被except: continue内部的loop_forever_sleep代码忽略try。只需从except循环中移除while True / def loop_forever_sleep(): x = 0 while True: print x x += 1 time.sleep(10) 块,它就可以正常工作:

{{1}}