我想设计一个线程,来处理一个定时器队列,如何处理才会比较高效??

hucong 2002-08-12 01:15:57
我遇到的问题:
1.如果单独用一个循环来处理,对每个定时器采用一个无限时间的等待,会很占用CPU,而且如果再在定时器队列中添加一个定时时间比当前小的定时器,就会得不到相应.定时器队列需要按照从小到大的时候排序
2.windows系统每隔20ms,就切换到系统空间去,检查内核对象的状态,我如何设计一个等待定时器报时的等待时间(我暂且设为25ms).
3.假设丢列中已经一个定时器,我通过检查其还剩余的时间(dwMilliseconds)与25ms比较,如果比25ms还要大,让线程去等待一个事件(等待时间为dwMilliseconds - 25).如果定时器队列中有个定时时间更小的定时器,我就触发上述的事件,让线程继续运行.(本来我是用Sleep来处理的,但我没有办法来唤醒它)
4.如果定时器队列中没有定时器,那么线程就等一个队列不为空的事件.
5.下面是线程的函数体,哪位大侠设计过类似的东西的,告诉我心得,我需要更好改进我的这个设计.如果谁需要完整代码,留下email,我给你们发过去.

while(m_isRun)
{
int length = m_timerlist.size() ;
if(0 == length)
m_eventHaveTimer.Wait ();

for(int i = 0;i < length;i++)
{
TTimer * pTimer = m_timerlist[i];
ASSERT_POINTER(pTimer,TTimer);//pTimer must not be NULL

DWORD dwStartTime = pTimer->GetStartTime ();
DWORD dwCurrentTime = ::GetTickCount ();
DWORD dwTime = pTimer->GetTime ();

if(dwTime > dwCurrentTime - dwTime)
{
DWORD dwMilliseconds =
pTimer->GetTime () - (dwCurrentTime - dwStartTime);
if(dwMilliseconds > 25 )
{
switch(m_eventSmallerTimer.Wait ())
{
case WAIT_FAILED:
break;
case WAIT_OBJECT_0:
m_eventSmallerTimer.Reset ();
break;
case WAIT_TIMEOUT: //Sleep(dwMilliseconds - 25);
break;
}
}
}

DWORD ret = ::WaitForSingleObject (pTimer->GetHandle (),0);
if( WAIT_FAILED == ret)
{
Erase(pTimer);
continue;
}
else if( WAIT_TIMEOUT == ret)
{
continue;
}
else if( ret == WAIT_OBJECT_0 )
{
CString str;
DWORD time = pTimer->GetTime ();
DWORD realtime = pTimer->GetRealTime ();
str.Format (
"timer:0x%X arrive at here! Time:%dms RealTime:%dms %f\n",
pTimer,time,realtime,fabs((double)realtime - time) *
100 / time);
Erase (pTimer);
TRACE0(str);
}
}//end for
}//end while
...全文
119 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
huangwu007 2002-08-12
  • 打赏
  • 举报
回复
我提供的只是做定时器的一种算法,而精度则取决于硬件和操作系统了,当然跟算法也有关系
hucong 2002-08-12
  • 打赏
  • 举报
回复
系统都提供定时器,但很都说那个精度不高,不高在何处?如果我们自己设计一个定时器,效率从何得来??我利用系统提供得定时器,精度一般在50ms左右
huangwu007 2002-08-12
  • 打赏
  • 举报
回复
这跟你要求的精度有关系了,如果你只是精确到10ms,那你就10ms查询一次你的定时器队列

定时器的数据结构可以这样设计:
头节点是距离最近的定时器,后一个节点记录与前一个节点的时间差,每次循环只要读头节点,修改剩余时长,当剩余时长==0时,表示时间到则出队列,触发该定时事件
hucong 2002-08-12
  • 打赏
  • 举报
回复
不好意思,上述的代码中的
switch(m_eventSmallerTimer.Wait ())
应该为
switch(m_eventSmallerTimer.Wait (dwMilliseconds))

70,019

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧