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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,739评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,791评论 25 709
  • 2013年9月2日 星期一 晴 在这一天,所有的人都上学了。 只有妈妈一个人在家,她会自己上网看电视吗?她自己一个...
    岑白笺阅读 1,839评论 0 0
  • 分科已经一个周了,我坐在走廊靠窗第一排的位置。自习课,做完练习,就望向了窗外,天很蓝,云很白,还依稀可以看见有几个...
    沅芷Kathy阅读 1,118评论 0 1
  • 【哈佛心语】 忠实于自己,忠实于自己的信仰,这是一种智慧。 ——华盛顿 【故事殿堂】 一个人最难能可贵的地方,是他...
    弹剑唱阳春阅读 3,582评论 1 1