Python3函数限时运行/超时停止

作者: xkang | 来源:发表于2018-01-24 15:33 被阅读326次

    0 问题引入

    最近写了爬虫并封装成了一个实时服务api接口,但是爬虫需要大概20s-30s才能完成,而且超时造成的失败也不能很快的反馈给客户端。
    通过查看一些资料和与他人讨论有以下几种方式可以解决这个问题:

    • 启动两个线程,爬虫任务放在一个线程里,定时任务放在一个线程里,如果时间达到,则终止爬虫任务线程
    • 利用信号量机制+装饰器模式来实现定时,而不用改变原有函数。
      第一种方法没有找到线程停止的方法所以也没有深入考虑。最后决定尝试第二种方法

    1 信号量机制的坑

    在python里使用信号量需要引入内置的signal包,但是信号量机制是依托于操作系统的,所以网上一些示例代码在windows环境下运行会报错!!!
    所以代码的调试必须转动Linux下,为了不(bu)重复(xie)造轮子(daima),这里要隆重介绍超时装饰器包timeout-decorator

    2 timeout-decorator包

    观察了timeout-decorator包的定时器实现,发现也是基于装饰器和信号量机制实现。

    • 安装
    pip install timeout-decorator
    
    • 使用示例1:
    import time
    import timeout_decorator
    
    @timeout_decorator.timeout(3)
    def mytest():
        time.sleep(5)
        return 5
    mytest()
    

    上面的代码超时设置为3s,运行后会抛出TimeoutException。

    • 使用示例2:
      默认情况下,timeout_decorator运用信号量来限制给定函数的执行时间。如果你的函数不是在main线程中(例如是一个web应用的worker线程)执行,那么这个方法就不行了。对这种情况有一个替代的超时策略---通过使用多进程。为了使用它,只要将use_signals=False添加到timeout decorator函数中。
    import time
    import timeout_decorator
    
    @timeout_decorator.timeout(3, use_signals=False)
    def mytest():
        time.sleep(5)
        return 5
    mytest()
    

    在其他地方使用超时函数时记得要加上try except语句捕获异常并做相应处理

    3 参考

    timeout-decorator 0.4.0

    相关文章

      网友评论

      • 郭百度:try:
        mytest()
        except timeout_decorator.timeout_decorator.TimeoutError:
        print('timeout')

      本文标题:Python3函数限时运行/超时停止

      本文链接:https://www.haomeiwen.com/subject/wsquaxtx.html