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()函数的误差应该会小些。

最新文章

  1. Linux下集群的搭建
  2. MySQL Replication 优化和技巧、常见故障解决方法
  3. SRM 616 ColorfulCoins
  4. Android 多种方式正确的加载图像,有效避免oom
  5. C#中foreach语句的迭代器实现机制
  6. Android string.xml error: Apostrophe not preceded by \
  7. 最艰难的采访IT公司ThoughtWorks代码挑战——FizzBuzzWhizz游戏
  8. clion idea jetbrain windows下搞c/c++
  9. 折腾Java设计模式之解释器模
  10. python学习6---排序问题
  11. opendistro 试用
  12. JSTL配置文件下载地址
  13. Win10上安装Keras 和 TensorFlow(GPU版本)
  14. Java基础96 ajax技术的使用
  15. 机器学习 - 开发环境安装pycharm + tensorflow集成篇
  16. [leetcode] 21. Implement strStr()
  17. Fiddler关闭后打不开网页
  18. LNK2019: 无法解析的外部符号(函数实现没有加namespace前缀导致)
  19. 64位linux下rpm安装mysql的5.5.55版本
  20. cloudermanger安装时需要安装或彻底正确卸载再安装orcal-java7-installer、oracle-java7-set-default(ubuntu14.04版本)(图文详解)

热门文章

  1. 微软职位内部推荐-Senior SDE for Cloud Platform
  2. 文件/图片,批量上传【神器】--WebUploader
  3. 在DataTable中执行DataTable.Select("条件")
  4. 在一个工程管理多个应用-b
  5. C# 读XML文件
  6. vc编程时说“Cannot open include file: 'unistd.h': No such file or directory”
  7. Mysql InnoDB彻底释放磁盘空间
  8. HDU1437+模拟
  9. java中存在的内存泄漏
  10. 思科模拟器软件教程---教你如何划分Vlan