Timeout a function (windows)?

前端 未结 2 1749
孤城傲影
孤城傲影 2020-11-30 06:01

I am trying to implement timeout for a particular function. I have checked many of the questions in SE and couldn\'t find any solution which fits my problem, because:

<
相关标签:
2条回答
  • 2020-11-30 06:33

    @acushner's answer adapted for python 3.5:

    from threading import Thread
    import functools
    
    def timeout(seconds_before_timeout):
        def deco(func):
            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                res = [Exception('function [%s] timeout [%s seconds] exceeded!' % (func.__name__, seconds_before_timeout))]
                def newFunc():
                    try:
                        res[0] = func(*args, **kwargs)
                    except Exception as e:
                        res[0] = e
                t = Thread(target=newFunc)
                t.daemon = True
                try:
                    t.start()
                    t.join(seconds_before_timeout)
                except Exception as e:
                    print('error starting thread')
                    raise e
                ret = res[0]
                if isinstance(ret, BaseException):
                    raise ret
                return ret
            return wrapper
        return deco
    
    0 讨论(0)
  • 2020-11-30 06:48

    I think a good way to approach this is to create a decorator and use the Thread.join(timeout=seconds) method. Bear in mind that there's no good way to kill the thread, so it will continue to run in the background, more or less, as long as your program is running.

    First, create a decorator like this:

    from threading import Thread
    import functools
    
    def timeout(timeout):
        def deco(func):
            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                res = [Exception('function [%s] timeout [%s seconds] exceeded!' % (func.__name__, timeout))]
                def newFunc():
                    try:
                        res[0] = func(*args, **kwargs)
                    except Exception as e:
                        res[0] = e
                t = Thread(target=newFunc)
                t.daemon = True
                try:
                    t.start()
                    t.join(timeout)
                except Exception as je:
                    print ('error starting thread')
                    raise je
                ret = res[0]
                if isinstance(ret, BaseException):
                    raise ret
                return ret
            return wrapper
        return deco
    

    Then, do something like this:

    func = timeout(timeout=16)(MyModule.MyFunc)
    try:
        func()
    except:
        pass #handle errors here
    

    You can use this decorator anywhere you need with something like:

    @timeout(60)
    def f():
        ...
    
    0 讨论(0)
提交回复
热议问题