Live555研究之二Sleep实现

转自:http://www.cnblogs.com/ityujian/p/3139595.html


Live555研究之二Sleep实现


Live555通过一个while循环来不断读取socket,判断是否有连接进来,但是Live555并没有使用Sleep函数来让线程休眠多少毫秒来降低CPU占用率。Live555是通过select函数来实现Sleep,先计算出距离下次事件的时间,然后让select超时为该时间值(tv_timeToDelay),如果有连接进来则处理,没有则等待直到超时。 
int selectResult = select(fMaxNumSockets, &readSet, &writeSet, &exceptionSet, &tv_timeToDelay); 

static BasicTaskScheduler* createNew(unsigned maxSchedulerGranularity = 10000/*microseconds*/); 
创建BasicTaskScheduler对象的时候会将10毫秒作为默认的事件时间间隔,创建定时任务。 
DelayQueue是一个循环队列,在BasicTaskScheduler::SingleStep() 结束前会调用该队列的handleAlarm()函数,在handleAlarm()内会首先释放当前Event,然后调用Event的handleTimeout()函数,由于在DelayQueue的派生类AlarmHandler中已经把handleTimeout()函数改写了,每次调用之前会先通过函数指针调用函数来创建一个新的AlarmHandle。然后再调用DelayQueueEntry::handleTimeout()。这样保证每处理完一个Event,又会创建一个新的Event,确保工程能执行下去,而且队列里的节点又不会无限制增长。

virtual void handleTimeout() { 
  (*fProc)(fClientData); 
  DelayQueueEntry::handleTimeout(); 


对于循环队列DelayQueueEntry,如果要插入新的Event,将会匹配时间修改当前Event,再把新Event插入的到当前Event的前面,再修改前后指针,形成新的循环队列。 
void DelayQueue::addEntry(DelayQueueEntry* newEntry) { 
  synchronize();

  DelayQueueEntry* cur = head(); 
  while (newEntry->fDeltaTimeRemaining >= cur->fDeltaTimeRemaining) { 
    newEntry->fDeltaTimeRemaining -= cur->fDeltaTimeRemaining; 
    cur = cur->fNext; 
  }

  cur->fDeltaTimeRemaining -= newEntry->fDeltaTimeRemaining;

  // Add "newEntry" to the queue, just before "cur": 
  newEntry->fNext = cur; 
  newEntry->fPrev = cur->fPrev; 
  cur->fPrev = newEntry->fPrev->fNext = newEntry; 


计算延迟时间是在函数DelayQueue::synchronize()中进行的,保存当前时间,然后和上一次同步的时间做比较,判断还有多少富余时间,再将富余时间返回。 

以前开发流媒体服务器,在进行帧率处理时使用Sleep让线程等待,但是Sleep误差在40毫秒左右,导致声音不流畅,后来还是改用其他函数进行优化。socket中的select()函数的误差应该会小些。


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值