前言:

跟大家在群里聊了关于apscheduler的一些话题,大家尤其对他的时间管理感兴趣, 趁现在有空,花点时间做个分享。  其实在以前是写过apscheduler的源代码分析文章,写得太泛了,这次主要着重于定时器的相关逻辑。  python下的定时任务框架有那么几个选择,像sched,celery,apscheduler都可以做,相对来说功能和扩展最好的当属apscheduler了。   话说,我曾经还给apscheduler提交过一个crontab 格式的扩展,最后没merge,原因不明….  

该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新.   http://xiaorui.cc/?p=4228

首先从一个测试说起,代码如下:

执行的结果确实是我们想看到的,很理想  !  

那么我们应该去思考下,Apscheduler是如何管理这些定时器的 ?  我曾经写过各种各样的定时器, 用redis zset实现定时器,用gevent实现过, 用小堆实现过, 用epoll timerfd也实现过…  有兴趣的朋友可以看看我的github和博文. 

追了一下代码发现 apscheduler 默认是没有采用这些方法, 而使用了一个更加简单的方法. 


在这里我们知道他会wait这个事件,超时的时间为所有定时器中最小的那个。。。   举个例子现在是1秒, 有三个任务分别是10秒、15秒、20秒后执行? 那么我们就再等待 10 – 1 秒。

那么这里会有一个效率的问题 !  当job列表任务很多的时候,难道每次都O(N)的时间复杂度计算下次event等待时间? 

当然不可能这么粗暴  !     

Apscheduler 使用jobstore为memery模式时候,会构建一个列表来用存放任务,当我们 add_job 添加一个新任务的时候,这个列表按时间排序存放,可以理解为有序列表,查找存放的点当然是二分查找算法了, 他的时间复杂度是 O(logN) .   这样实现的效果跟我前面说的小堆是一样的.   


如果 apscheduler的定时任务已经跑起来了, 这时候你新加了一个定时周期任务?  但是你这边还在wait?  不要担心,当你调用add_job时, _real_add_job会帮你唤醒的.  当被唤醒了后,Apscheduler又继续寻找到期任务及等待时间。 

Apscheduler扩展了很多的jobstore存储方案,那么我们挑几个看看他们的实现方法. 

file: jobstores/redis.py

当然mysql也是依赖时间戳的概念,也是需要有排序的。

就先这样吧,.  到此为止我们差不多得知apscheduler的scheduler和job的设计,下次有时间再来分析下apscheduler的其他组件源码。

END.



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!
{ 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 }

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!

基于timerfd epoll开发的io定时器 [下]

接着上下文 接着上文, 上次内容是说epoll timerfd的原理和函数方法,下文主要是python epoll timerfd的之间的调用. 该文章写的有些乱,欢...

阅读全文