织梦CMS - 轻松建站从此开始!

罗索

pjsip协议栈中定时器的实现详解

落鹤生 发布于 2010-07-08 09:32 点击:次 
pjsip中管理定时器的数据结构是堆,是采用小顶堆来实现的,该堆为一棵完全二叉树,该完全二叉树采用顺序结构(即是数组)实现。
TAG:

SIP协议中的用于超市重传或其他用途的定时器(timer)很多,令人头大,很久以前就想到如何实现这些定时器,以前用C coding的时候,就是简单地sleep一下来延时。今天仔细分析了pjsip协议栈中定时器的实现源代码。灰常兴奋地看了...

pjsip也是借鉴别人的实现方法,这在其官网上,作者如是说。

pjsip中管理定时器的数据结构是,是采用小顶堆来实现的,该堆为一棵完全二叉树,该完全二叉树采用顺序结构(即是数组)实现。

对于每一个定时器,pjsip中用一个定时器实体结构体来描述,该实体结构体如下:

 

  1. /** 
  2. * This structure represents an entry to the timer. 
  3. */ 
  4. struct pj_timer_entry 
  5.     /** 
  6.      * User data to be associated with this entry. 
  7.      * Applications normally will put the instance of object that 
  8.      * owns the timer entry in this field. 
  9.      */ 
  10.     void *user_data; 
  11.  
  12.     /** 
  13.      * Arbitrary ID assigned by the user/owner of this entry. 
  14.      * Applications can use this ID to distinguish multiple 
  15.      * timer entries that share the same callback and user_data. 
  16.      */ 
  17.     int id; 
  18.  
  19.     /** 
  20.      * Callback to be called when the timer expires. 
  21.      */ 
  22.     pj_timer_heap_callback *cb; 
  23.  
  24.     /** 
  25.      * Internal unique timer ID, which is assigned by the timer heap. 
  26.      * Application should not touch this ID. 
  27.      */ 
  28.     pj_timer_id_t _timer_id; 
  29.  
  30.     /** 
  31.      * The future time when the timer expires, which the value is updated 
  32.      * by timer heap when the timer is scheduled. 
  33.      */ 
  34.     pj_time_val _timer_value; 
  35. }; 

注释已经很清楚了,不细说啦......

    另一个很重要的实体结构是延时的时间结构体,其包括时间的s和ms两个域:

 

  1. /** 
  2. * Representation of time value in this library. 
  3. * This type can be used to represent either an interval or a specific time 
  4. * or date. 
  5. */ 
  6. typedef struct pj_time_val 
  7.     /** The seconds part of the time. */ 
  8.     long    sec; 
  9.  
  10.     /** The miliseconds fraction of the time. */ 
  11.     long    msec; 
  12.  
  13. } pj_time_val; 

   上述说了小顶堆,以及定时器实体,还有时间结构,那么究竟怎么实现定时功能呢?

不说大家也猜得到,我们必须提供某种机制来判断定时器是否timeout,怎么判断?pjsip中采用轮询的方式,不断轮询定时器堆(定时器实体构成一个定时器小顶堆)根元素,来判断是否超时的。

   首先,pj_timer_heap_create()创建定时器堆;

   然后,pj_timer_heap_schedule()来调度定时器,也就是插入到定时器堆中,该函数实现堆的基本操作,一旦一个定时器结构体加入堆,就开始计时,此时,该加入的定时器结构体记录了入堆的当前时刻加上延时时间,也就是将来的定时到的某个时刻;

   然后,pj_timer_heap_poll()在某线程或者主线程中不断轮询定时器堆的根元素,并且获取轮询时候的当前时刻,用它来和根元素的超时刻比较,如果根元素的记录时刻小于当前时刻,那么该定时器超时,然后将其从堆中删掉,并调用回调函数,进行超时操作。

上述的定时精度不能说十分准确,单基本够用。

后记:

   其实定时器的实现原理很简单,就是创建一种机制来判断当前时刻某定时器是否超时。这个过程是个循环的过程。曾经用c语言采用sleep的方式实现定时,使用函数指针来传回调函数为用户提供API,但是精度远不如上述方式。

(chenjily)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201007/9797.html]
本文出处:百度博客 作者:chenjily
顶一下
(2)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容