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()函数的误差应该会小些。
Live555研究之二Sleep实现的更多相关文章
- LIVE555研究之五:RTPServer(二)
port是一样的. DynamicRTSPServer 继承关系: Medium是非常多类的基类.内部定义了指向环境类的引用和一个char类型媒体名称.并定义了依照媒体名称,查找相应媒体的成员函数lo ...
- Live555研究之中的一个 源码编译
Live555研究之中的一个 源代码编译 Live555 是一个为流媒体提供解决方式的跨平台的C++开源项目,它 ...
- 关于ADMM的研究(二)
关于ADMM的研究(二) 4. Consensus and Sharing 本节讲述的两个优化问题,是非常常见的优化问题,也非常重要,我认为是ADMM算法通往并行和分布式计算的一个途径:consens ...
- live555源码研究(二)------TaskScheduler类
一.TaskScheduler类作用 1,他是使用环境的一部分. 2,他提供了对socket触发事件的管理. 二.类TaskScheduler继承关系图 二.TaskScheduler成员函数 1,s ...
- LIVE555研究之三:LIVE555基础
LIVE555基础 LIVE555是为流媒体提供解决方式的跨平台C++开源项目.从今天起我们将正式開始深入LIVE555代码. 一.各库简要介绍 LIVE555下包括LiveMedia.UsageEn ...
- Live555 分析(二):服务端
live555支持单播和组播,我们先分析单播的流媒体服务端,后面分析组播的流媒体服务端. 一.单播的流媒体服务端: // Create the RTSP server: RTSPServer* rts ...
- Unity使用C++作为游戏逻辑脚本的研究(二)
文章申明:本文来自JacksonDunstan的博客系列文章内容摘取和翻译,版权归其所有,附上原文的链接,大家可以有空阅读原文:C++ Scripting( in Unity) 上一篇文章写完,有同学 ...
- Live555研究之一 源代码编译
Live555 是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了对标准流媒体传输协议如RTP/RTCP.RTSP.SIP等的支持.Live555实现了对多种音视频编码格式的音视频数据的流化 ...
- 研究QGIS二次开发笔记(一)
为了在QT程序中嵌入一个地图,最终选择了QGIS来干这件事.选型阶段真是呵呵.我折腾的是QGIS2.4.0. 首先,到官方网站下载安装QGIS.如果你跟我一样懒的话,可能希望下载一个已经编译好的win ...
随机推荐
- 【BZOJ1251】序列终结者
Description 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这 ...
- Guide to Database Migration from Microsoft SQL Server using MySQL Workbench
http://mysqlworkbench.org/2012/07/migrating-from-ms-sql-server-to-mysql-using-workbench-migration-wi ...
- sb 讲解 (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]]
代码:(!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]] 输出sb. 分段解析: 首先解析s: (! ...
- Matlab划分测试集和训练集
% x是原数据集,分出训练样本和测试样本 [ndata, D] = size(X); %ndata样本数,D维数 R = randperm(ndata); %1到n这些数随机打乱得到的一个随机数字序列 ...
- 如何编写敏捷开发中的user story
http://blog.csdn.net/chengyb74/article/details/4762247 对于敏捷开发来说,User Story是开发的基础,它不同于传统的瀑布式开发方式,而是把原 ...
- HDU4704+费马小定理
费马小定理题意:求s1+s2+s3+...+sn;si表示n划分i个数的n的划分的个数,如n=4,则s1=1,s2=3 利用隔板定理可知,就是求(2^n-1)%mod-----Y 现在已知 ...
- linux ps查看进程命令
linux ps查看进程命令ps命令作用:将某个时间点的程序运作情况撷取下来 实例: [root@linux ~]# ps aux [root@linux ~]# ps -lA [root@linux ...
- AAC ADTS AAC LATM 格式分析
http://blog.csdn.net/tx3344/article/details/7414543# 目录(?)[-] ADTS是个啥 ADTS内容及结构 将AAC打包成ADTS格式 1.ADTS ...
- 130. Surrounded Regions
题目: Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is capt ...
- Android invalidate()自动清屏,屏幕刷新
invalidate()是用来刷新View的,必须是在UI线程中进行工作.比如在修改某个view的显示时,调用invalidate()才能看到重新绘制的界面.invalidate()的调用是把之前的旧 ...