造一个轮子

对的,我又重新造了一个轮子! 关于周期定时器的轮子。 以前在python环境下,用二叉堆和gevent later写过单机的定时器,后来借用redis的sorted set 加lua实现了分布式的定时器任务管理。 但我坚决不满足, 我一直想实现一个类似libevent,libev那种包含各种功能的事件库,但个人能力及其有限…    


该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新.

http://xiaorui.cc/?p=3681


那么这根我们定时器的实现有啥关系? 因为libevent有定时器的功…    我去年的时候实现过一个类似gevent的io调度器,但一直没想好定时器该如何的实现,一开始是使用epoll wait跟二叉堆结构交叉来实现的,  每次做调度的时候都要看看是否有定时任务触发,  后来是独立一个线程扫描二叉堆,通过fd来让调度器唤醒.    总的来说很恶…. 


Timerfd 的优缺点

首先说说使用epoll管理timerfd的优缺点

优点是,你可以随意的使用timerfd创建定时任务和周期性任务,然后扔到epoll里,让内核去帮你监听事件,非常省事…

缺点是麻烦, 性能没有想象中的高.

如果你本身在使用围绕epoll为核心的调度器,那么很容易把socket事件,信号事件,定时事件都抽象合体在epoll来监听。

二叉堆的实现相对更简单,但是他的问题也有不少, 首先是周期性任务,你开一个独立线程去创建任务,但如果每个任务的周期不同,该怎么适配?
当然,这不是问题.

我很久以前就知道timerfd的特性,但一直没机会去尝试下。  我这次用PyObject封装了timerfd的c api, 因为python标准库里不存在timerfd定时接口。


我猜有人会问我,timerfd是什么?

timerfd是Linux为用户程序提供的一个定时器接口。这个接口基于文件描述符,通过文件描述符的可读事件进行超时通知,一般是被用于select/epoll的应用场景。


timerfd vs select timeout 区别 ?

- timerfd_create 把时间变成了一个文件描述符,该“文件”在定时器超时的那一刻变得可读,这样就能很方便地融入到 select/poll 框架中,用统一的方式来处理 IO 事件和超时事件。
- 利用select, poll的timeout实现定时功能,它们的缺点是定时精度只有毫秒,远低于 timerfd_settime 的定时精度。

timerfd C API 使用方法

讲讲C 的 Timerfd相关函数介绍.   http://man7.org/linux/man-pages/man2/timerfd_create.2.html


timerfd_create函数方法:

timerfd_settime函数:

用于启动和停止定时器,fd为timerfd_create获得的定时器文件描述符,flags为0表示是相对定时器,为TFD_TIMER_ABSTIME表示是绝对定时器。const struct itimerspec *new_value表示设置超时的时间。

int timerfd_settime(int ufd, int flags, const struct itimerspec * utmr, struct itimerspec * otmr);

此函数用于设置新的超时时间,并开始计时。
ufd,timerfd_create返回的文件句柄。
flags,为1代表设置的是绝对时间;为0代表相对时间。
utmr为需要设置的时间。
otmr为定时器这次设置之前的超时时间。
一般来说函数返回0代表设置成功。

在timerfd里有一个及其重要的数据结构:


需要注意的是itimerspec 结构成员表示的意义:

it_value是首次超时时间,需要填写从clock_gettime获取的时间,并加上要超时的时间。 it_interval是后续周期性超时时间,是多少时间就填写多少。

it_interval不为0则表示是周期性定时器,大于0,是周期性的时间.。

it_value和it_interval都为0表示停止定时器。

timerfd_gettime此函数用于获得定时器距离下次超时还剩下的时间。如果调用时定时器已经到期,并且该定时器处于循环模式(设置超时时间时struct itimerspec::it_interval不为0),那么调用此函数之后定时器重新开始计时。 


timerfd的简单使用例子,大家对照上面讲述的timerfd接口学习下。  

上面的代码是timerfd的基本用法,我们在看看timerfd epoll的C API使用方法.  

此文为上小结,下小节会说下python timerfd epoll的使用方法。  我已经把python epoll timerfd封装一个包,大家直接调用就可以了。 


END.



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

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

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

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

阅读全文

技术分享《一个异步io调度框架的实现》

今下午在公司内部做了高端话题的分享,话题是异步io调度器是怎么实现的. 另外结合socket服务器又该如何调度处理? 这次的PPT写的有些简略,但基本说明了构...

阅读全文