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