由上面的分析,可以看到各种定时器实现算法的复杂度:
表 1. 定时器实现算法复杂度
实现方式 StartTimer StopTimer PerTickBookkeeping
基于链表 O(1) O(n) O(n)
基于排序链表 O(n) O(1) O(1)
基于最小堆 O(lgn) O(1) O(1)
基于时间轮 O(1) O(1) O(1)
如果需要能在线程环境中使用的定时器,对于基于链表的定时器,可能需要很小心的处理信号的问题;而 POSIX timer [ 2 ]接口的定时器,只具有进程的语义,如果想在多线程环境下也 n 能使用,可以使用 Linux 提供的 timerfd_create(2) 接口。如果需要支持的定时器数量非常的大,可以考虑使用基于最小堆和时间轮的方式来实现。
下载样例代码 test-signal.c 7KB
参考资料
George Varghese , Tony Lauck. Hashed and Hierarchical Timing Wheels: Efficient Data Structures for Implementing a Timer Facility ,这篇论文分析了各种定时器实现方法,并提出了时间轮的概念。如果你想很好的实现一个定时器,这篇论文你需要反复阅读。
Open Group 对 POSIX timer 的描述 ,如果你对 UNIX 的标准有兴趣,推荐你在该网站下一份最新的 Specifications,并且,这份 Specifications 的描述相当容易读,linux 应用层的编程,它是我除了 Steven 的书之外的第一选择。
是一个 Open Source 的 VoIP 项目,如果你不关心 VoIP,该项目中提供的 pjlib 库也值得关注,它是一个在嵌入式环境下的通用基础库实现的典范。
~provos/libevent/ 最出名的事件通知库之一,它的内部使用基于最小堆实现的优先级队列处理包括时间,信号等各种事件。
Bo Berry 在文章“An embedded Single Timer Wheel” 中描述了一个简单时间轮算法实现的定时器。
Linux 2.6.31-rc6 的源代码。
Molnar 对 linux 中的时间轮的实现做了最好的解释。
Thomas H. Cormen,Charles E. Leiserson,Ronald L. Rivest,Clifford Stein 著.算法导论 ( 第二版 ) .北京:机械工业出版社,2006:73-82 。
关于作者
赵军,2005 年毕业于华中科技大学电气与电子工程学院,有 3 年基于 Linux 的 Router 开发经验,开发过基于 Linux 的高清 / 标清视频解码器,现在则开发基于 Linux 的图像处理平台,一直关注 Linux 在网络方面的发展。