我尝试使用timeSetEvent
每隔500毫秒调用一次看门狗功能。
通常看门狗没有任何问题。但是,当DVD插入驱动器时,由于系统正忙于读取磁盘,因此我最多不会收到8秒的回调。使用WindowsQueue
计时器并不是那么糟糕,我得到了4秒钟。
我的最后一次尝试是将线程优先级设置为时间关键,然后休眠500毫秒,但是8secs再次没有发生回调。
我仍在运行XP,但我不知道在以后的操作系统中进行的更改会使这更好。
我以DVD插入为例。我希望代码在可能的情况下对其他条件具有鲁棒性。
任何建议都非常感谢。
答案 0 :(得分:0)
我们发现从Windows获得不错的计时性能的最佳方法是完全避免计时器功能并自行推出;只是坐在一个紧凑的循环,吃CPU,直到下一个计时器事件的时间到来。 QueryPerformanceCounter
似乎是为此目的获得快速,高分辨率时间的最佳方式。尽你所能给运行这个循环的线程提供一个它将坚持的CPU核心,并且不会有任何其他的CPU时间。
但要注意:
一般情况下,如果您需要准确的计时,Windows就不适合这样做。
答案 1 :(得分:0)
您可以尝试使用此示例代码,意味着在单独的线程中使用以固定频率运行,在Windows XP上最高可达400hz(其中Sleep(1)可能需要大约2 ms)。当新卷准备好时,似乎存在系统范围的延迟,在这种情况下是DVD,但是如果打开外部USB硬盘驱动器,则会发生类似的延迟。似乎Windows XP开始扫描新卷,锁定了相当多的系统,甚至这个代码示例也可能受到影响,因为它使用Sleep(1)来减少cpu开销。您可以删除Sleep(1)代码,这将使其中一个cpu内核保持100%运行,并且插入DVD甚至可能会弄乱它。
/* code for a thread to run at fixed frequency */
typedef unsigned long long UI64; /* unsigned 64 bit int */
#define FREQ 2 /* frequency (500 ms) */
LARGE_INTEGER liPerfTemp; /* used for query */
UI64 uFreq = FREQ; /* process frequency */
UI64 uOrig; /* original tick */
UI64 uWait; /* tick rate / freq */
UI64 uRem = 0; /* tick rate % freq */
UI64 uPrev; /* previous tick based on original tick */
UI64 uDelta; /* current tick - previous */
UI64 u2ms; /* 2ms of ticks */
UI64 i;
/* ... */ /* wait for some event to start thread */
timeBeginPeriod(1); /* set period to 1ms */
Sleep(128); /* wait for it to stabilize */
u2ms = ((UI64)(liPerfFreq.QuadPart)+499) / ((UI64)500);
QueryPerformanceCounter((PLARGE_INTEGER)&liPerfTemp);
uOrig = uPrev = liPerfTemp.QuadPart;
for(i = 0; i < (uFreq*30); i++){
/* update uWait and uRem based on uRem */
uWait = ((UI64)(liPerfFreq.QuadPart) + uRem) / uFreq;
uRem = ((UI64)(liPerfFreq.QuadPart) + uRem) % uFreq;
/* wait for uWait ticks */
while(1){
QueryPerformanceCounter((PLARGE_INTEGER)&liPerfTemp);
uDelta = (UI64)(liPerfTemp.QuadPart - uPrev);
if(uDelta >= uWait)
break;
if((uWait - uDelta) > u2ms)
Sleep(1);
}
if(uDelta >= (uWait*2))
dwLateStep += 1;
uPrev += uWait;
/* fixed frequency code goes here */
/* along with some type of break when done */
}
timeEndPeriod(1); /* restore period */
答案 2 :(得分:0)
您是否查看了RegisterWaitForSingleObject函数(http://msdn.microsoft.com/en-us/library/windows/desktop/ms685061%28v=vs.85%29.aspx)?