SetTimer可以用作定时器,可是精度较低,大概15毫秒调用一次,请问有没有比此函数精度更高的方法,关键是不能占用CPU,多谢各位!
16 个解决方案
#1
有不占CPU的操作吗
#2
用多媒体定时间器吧,可以精确到1毫秒
UINT TimerScanStart(LPTIMECALLBACK fptc,int TimeCycle,BOOL bTime_OneShot)
{
UINT TimeID = 0;
TIMECAPS tc;
if(::timeGetDevCaps(&tc,sizeof(TIMECAPS))==TIMERR_NOERROR)
{
DWORD wAccuracy;
wAccuracy=min(max(tc.wPeriodMin,TIMER_ACCURACY),tc.wPeriodMax);
if(timeBeginPeriod(wAccuracy) == TIMERR_NOERROR )
{
// 参数 TIME_PERIODIC: 周期执行
if(TimeCycle >= wAccuracy && TimeCycle <= tc.wPeriodMax)
{
if(bTime_OneShot)
{//只执行一次
TimeID = ::timeSetEvent(TimeCycle,wAccuracy,fptc,(DWORD)this,TIME_ONESHOT);
}
else
{//周期执行
TimeID = ::timeSetEvent(TimeCycle,wAccuracy,fptc,(DWORD)this,TIME_PERIODIC);
}
}
timeEndPeriod(wAccuracy);
}
}
return TimeID ;
}
UINT TimerScanStart(LPTIMECALLBACK fptc,int TimeCycle,BOOL bTime_OneShot)
{
UINT TimeID = 0;
TIMECAPS tc;
if(::timeGetDevCaps(&tc,sizeof(TIMECAPS))==TIMERR_NOERROR)
{
DWORD wAccuracy;
wAccuracy=min(max(tc.wPeriodMin,TIMER_ACCURACY),tc.wPeriodMax);
if(timeBeginPeriod(wAccuracy) == TIMERR_NOERROR )
{
// 参数 TIME_PERIODIC: 周期执行
if(TimeCycle >= wAccuracy && TimeCycle <= tc.wPeriodMax)
{
if(bTime_OneShot)
{//只执行一次
TimeID = ::timeSetEvent(TimeCycle,wAccuracy,fptc,(DWORD)this,TIME_ONESHOT);
}
else
{//周期执行
TimeID = ::timeSetEvent(TimeCycle,wAccuracy,fptc,(DWORD)this,TIME_PERIODIC);
}
}
timeEndPeriod(wAccuracy);
}
}
return TimeID ;
}
#3
正点,过会试试。我指的不占CPU就是定时器“休眠”过程中,
它所在的线程能够让出系统资源。如Sleep()就是不占CPU的延时,
但我需要比它更精确的延时。各位高手,继续啊,不要停,急用
它所在的线程能够让出系统资源。如Sleep()就是不占CPU的延时,
但我需要比它更精确的延时。各位高手,继续啊,不要停,急用
#4
CreateWaitableTimer()创建内核定时器,可以帮你实现精度到最少至100ns的定时器,
够了吧。
够了吧。
#5
timeSetEvent 只能用16个吧
#6
timeSetEvent 确实只能用16个
#7
http://www.vckbase.com/document/viewdoc/?id=1301
#8
timeSetEvent 确实只能用16个
不错,在一个进程中,真是很恶心!
不错,在一个进程中,真是很恶心!
#9
核实下:setTimer好象是55ms的精度
好像system.sys中隐藏了某个定时函数(就是在Windows.h中没有给出声明),待我回去查查
好像system.sys中隐藏了某个定时函数(就是在Windows.h中没有给出声明),待我回去查查
#10
恩?一个进程只能有16个,哪儿说的,或者是自己试出来的,还是自己跟踪出来的?我不知道,谁给解释一下
#11
当然是WaitableTime,精度能满足,还保持线程等待状态
#12
WaitableTimer
#13
我觉得就算是通过线程、事件Event也不要去碰什么定时器 会死的惨兮兮的
#14
性能计数器更精确些,不过不占用cpu怎么测量啊
#15
楼主有没有想过,在windows这种多线程非实时操作系统中,实现精度为1ms的定时,几乎是不可能的么?
即使你用多媒体定时器,比如,在一个线程A中定义一个每1ms触发一次的定时器,假如始终都是这一个线程占有cpu时间的话,那自然可以实现1ms精确定时。但在多进程的分时操作系统中,有可能线程A在定时器开始计时后,A被阻塞,转而执行其他高优先级的线程,系统并不能保证在1ms时间到了后,一定能马上把cpu时间切换到A,因此也就无法执行你的定时器回调函数。或许等到线程A获得cpu时间时,早已经过了1ms的时间了。
这并不是系统的缺陷,而是多线程非实时系统的固有特性。
因此,我觉得楼主在windows系统中极端的追求这种高精度并且不耗cpu时间的定时,是不大可能的。
即使你用多媒体定时器,比如,在一个线程A中定义一个每1ms触发一次的定时器,假如始终都是这一个线程占有cpu时间的话,那自然可以实现1ms精确定时。但在多进程的分时操作系统中,有可能线程A在定时器开始计时后,A被阻塞,转而执行其他高优先级的线程,系统并不能保证在1ms时间到了后,一定能马上把cpu时间切换到A,因此也就无法执行你的定时器回调函数。或许等到线程A获得cpu时间时,早已经过了1ms的时间了。
这并不是系统的缺陷,而是多线程非实时系统的固有特性。
因此,我觉得楼主在windows系统中极端的追求这种高精度并且不耗cpu时间的定时,是不大可能的。
#16
楼上的有道理,你就不访这样吧
hEvent=CreateEvent(...);
WaitForSingleObject(hEvent,你的定时);
CloseHandle(hEvent);
hEvent=CreateEvent(...);
WaitForSingleObject(hEvent,你的定时);
CloseHandle(hEvent);
#1
有不占CPU的操作吗
#2
用多媒体定时间器吧,可以精确到1毫秒
UINT TimerScanStart(LPTIMECALLBACK fptc,int TimeCycle,BOOL bTime_OneShot)
{
UINT TimeID = 0;
TIMECAPS tc;
if(::timeGetDevCaps(&tc,sizeof(TIMECAPS))==TIMERR_NOERROR)
{
DWORD wAccuracy;
wAccuracy=min(max(tc.wPeriodMin,TIMER_ACCURACY),tc.wPeriodMax);
if(timeBeginPeriod(wAccuracy) == TIMERR_NOERROR )
{
// 参数 TIME_PERIODIC: 周期执行
if(TimeCycle >= wAccuracy && TimeCycle <= tc.wPeriodMax)
{
if(bTime_OneShot)
{//只执行一次
TimeID = ::timeSetEvent(TimeCycle,wAccuracy,fptc,(DWORD)this,TIME_ONESHOT);
}
else
{//周期执行
TimeID = ::timeSetEvent(TimeCycle,wAccuracy,fptc,(DWORD)this,TIME_PERIODIC);
}
}
timeEndPeriod(wAccuracy);
}
}
return TimeID ;
}
UINT TimerScanStart(LPTIMECALLBACK fptc,int TimeCycle,BOOL bTime_OneShot)
{
UINT TimeID = 0;
TIMECAPS tc;
if(::timeGetDevCaps(&tc,sizeof(TIMECAPS))==TIMERR_NOERROR)
{
DWORD wAccuracy;
wAccuracy=min(max(tc.wPeriodMin,TIMER_ACCURACY),tc.wPeriodMax);
if(timeBeginPeriod(wAccuracy) == TIMERR_NOERROR )
{
// 参数 TIME_PERIODIC: 周期执行
if(TimeCycle >= wAccuracy && TimeCycle <= tc.wPeriodMax)
{
if(bTime_OneShot)
{//只执行一次
TimeID = ::timeSetEvent(TimeCycle,wAccuracy,fptc,(DWORD)this,TIME_ONESHOT);
}
else
{//周期执行
TimeID = ::timeSetEvent(TimeCycle,wAccuracy,fptc,(DWORD)this,TIME_PERIODIC);
}
}
timeEndPeriod(wAccuracy);
}
}
return TimeID ;
}
#3
正点,过会试试。我指的不占CPU就是定时器“休眠”过程中,
它所在的线程能够让出系统资源。如Sleep()就是不占CPU的延时,
但我需要比它更精确的延时。各位高手,继续啊,不要停,急用
它所在的线程能够让出系统资源。如Sleep()就是不占CPU的延时,
但我需要比它更精确的延时。各位高手,继续啊,不要停,急用
#4
CreateWaitableTimer()创建内核定时器,可以帮你实现精度到最少至100ns的定时器,
够了吧。
够了吧。
#5
timeSetEvent 只能用16个吧
#6
timeSetEvent 确实只能用16个
#7
http://www.vckbase.com/document/viewdoc/?id=1301
#8
timeSetEvent 确实只能用16个
不错,在一个进程中,真是很恶心!
不错,在一个进程中,真是很恶心!
#9
核实下:setTimer好象是55ms的精度
好像system.sys中隐藏了某个定时函数(就是在Windows.h中没有给出声明),待我回去查查
好像system.sys中隐藏了某个定时函数(就是在Windows.h中没有给出声明),待我回去查查
#10
恩?一个进程只能有16个,哪儿说的,或者是自己试出来的,还是自己跟踪出来的?我不知道,谁给解释一下
#11
当然是WaitableTime,精度能满足,还保持线程等待状态
#12
WaitableTimer
#13
我觉得就算是通过线程、事件Event也不要去碰什么定时器 会死的惨兮兮的
#14
性能计数器更精确些,不过不占用cpu怎么测量啊
#15
楼主有没有想过,在windows这种多线程非实时操作系统中,实现精度为1ms的定时,几乎是不可能的么?
即使你用多媒体定时器,比如,在一个线程A中定义一个每1ms触发一次的定时器,假如始终都是这一个线程占有cpu时间的话,那自然可以实现1ms精确定时。但在多进程的分时操作系统中,有可能线程A在定时器开始计时后,A被阻塞,转而执行其他高优先级的线程,系统并不能保证在1ms时间到了后,一定能马上把cpu时间切换到A,因此也就无法执行你的定时器回调函数。或许等到线程A获得cpu时间时,早已经过了1ms的时间了。
这并不是系统的缺陷,而是多线程非实时系统的固有特性。
因此,我觉得楼主在windows系统中极端的追求这种高精度并且不耗cpu时间的定时,是不大可能的。
即使你用多媒体定时器,比如,在一个线程A中定义一个每1ms触发一次的定时器,假如始终都是这一个线程占有cpu时间的话,那自然可以实现1ms精确定时。但在多进程的分时操作系统中,有可能线程A在定时器开始计时后,A被阻塞,转而执行其他高优先级的线程,系统并不能保证在1ms时间到了后,一定能马上把cpu时间切换到A,因此也就无法执行你的定时器回调函数。或许等到线程A获得cpu时间时,早已经过了1ms的时间了。
这并不是系统的缺陷,而是多线程非实时系统的固有特性。
因此,我觉得楼主在windows系统中极端的追求这种高精度并且不耗cpu时间的定时,是不大可能的。
#16
楼上的有道理,你就不访这样吧
hEvent=CreateEvent(...);
WaitForSingleObject(hEvent,你的定时);
CloseHandle(hEvent);
hEvent=CreateEvent(...);
WaitForSingleObject(hEvent,你的定时);
CloseHandle(hEvent);