欢迎来到天天文库
浏览记录
ID:30361864
大小:88.45 KB
页数:21页
时间:2018-12-29
《linux下定时器的实现方式分析》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、Linux下定时器的实现方式分析定时器属于基本的基础组件,不管是用户空间的程序开发,还是内核空间的程序开发,很多时候都需要有定时器作为基础组件的支持,但使用场景的不同,对定时器的实现考虑也不尽相同,本文讨论了在Linux环境下,应用层和内核层的定时器的各种实现方法,并分析了各种实现方法的利弊以及适宜的使用环境。首先,给出一个基本模型,定时器的实现,需要具备以下几个行为,这也是在后面评判各种定时器实现的一个基本模型[1]:StartTimer(Interval,TimerId,ExpiryAction)注册一个时间
2、间隔为Interval后执行ExpiryAction的定时器实例,其中,返回TimerId以区分在定时器系统中的其他定时器实例。StopTimer(TimerId)根据TimerId找到注册的定时器实例并执行Stop。PerTickBookkeeping()在一个Tick内,定时器系统需要执行的动作,它最主要的行为,就是检查定时器系统中,是否有定时器实例已经到期。注意,这里的Tick实际上已经隐含了一个时间粒度(granularity)的概念。ExpiryProcessing()在定时器实例到期之后,执行预先注册
3、好的ExpiryAction行为。上面说了基本的定时器模型,但是针对实际的使用情况,又有以下2种基本行为的定时器:Single-ShotTimer这种定时器,从注册到终止,仅仅只执行一次。RepeatingTimer这种定时器,在每次终止之后,会自动重新开始。本质上,可以认为RepeatingTimer是在Single-ShotTimer终止之后,再次注册到定时器系统里的Single-ShotTimer,因此,在支持Single-ShotTimer的基础上支持RepeatingTimer并不算特别的复杂。在2.4
4、的内核中,并没有提供POSIXtimer[2]的支持,要在进程环境中支持多个定时器,只能自己来实现,好在Linux提供了setitimer(2)的接口。它是一个具有间隔功能的定时器(intervaltimer),但如果想在进程环境中支持多个计时器,不得不自己来管理所有的计时器。setitimer(2)的定义如下:清单1.setitimer的原型#includesys/time.hintsetitimer(intwhich,conststructitimerval*new_value,structitimerval
5、*old_value);setitimer能够在Timer到期之后,自动再次启动自己,因此,用它来解决Single-ShotTimer和RepeatingTimer的问题显得很简单。该函数可以工作于3种模式:ITIMER_REAL以实时时间(realtime)递减,在到期之后发送SIGALRM信号ITIMER_VIRTUAL仅进程在用户空间执行时递减,在到期之后发送SIGVTALRM信号ITIMER_PROF进程在用户空间执行以及内核为该进程服务时(典型如完成一个系统调用)都会递减,与ITIMER_VIRTUAL
6、共用时可度量该应用在内核空间和用户空间的时间消耗情况,在到期之后发送SIGPROF信号定时器的值由下面的结构定义:structitimerval{structtimevalit_interval;/*nextvalue*/structtimevalit_value;/*currentvalue*/};structtimeval{longtv_sec;/*seconds*/longtv_usec;/*microseconds*/};setitimer()以new_value设置特定的定时器,如果old_value非
7、空,则它返回which类型时间间隔定时器的前一个值。定时器从it_value递减到零,然后产生一个信号,并重新设置为it_interval,如果此时it_interval为零,则该定时器停止。任何时候,只要it_value设置为零,该定时器就会停止。由于setitimer()不支持在同一进程中同时使用多次以支持多个定时器,因此,如果需要同时支持多个定时实例的话,需要由实现者来管理所有的实例。用setitimer()和链表,可以构造一个在进程环境下支持多个定时器实例的Timer,在一般的实现中的PerTickBoo
8、kkeeping时,会递增每个定时器的elapse值,直到该值递增到最初设定的interval则表示定时器到期。基于链表实现的定时器可以定义为:typedefinttimer_id;/**Thetypeofcallbackfunctiontobecalledbytimerschedulerwhenatimer*hasexpired.**@paramidThetimerid
此文档下载收益归作者所有