阅读:3141回复:8
KeWaitForSingleObject延时,太离谱了吧
在系统线程里
VOID ThreadProc(PWDMDRV_DEVICE_EXTENSION pdx) { LARGE_INTEGER liTimeout; KeQuerySystemTime(&liTimeout); while (TRUE) { liTimeout.QuadPart += (LONGLONG)1000000; // 100ms NTSTATUS status = KeWaitForSingleObject(&pdx->Event, Executive, KernelMode, FALSE, &liTimeout); LARGE_INTEGER liNow; KeQuerySystemTime(&liNow); // ... } // ... } 输出的 liTimeout 和 liNow 如下: 0: 127155521257812500 2003-12-10 17:48:45.781 127155521257812500 2003-12-10 17:48:45.781 1: 127155521258812500 2003-12-10 17:48:45.881 127155521258906250 2003-12-10 17:48:45.890 2: 127155521259812500 2003-12-10 17:48:45.981 127155521259843750 2003-12-10 17:48:45.984 3: 127155521260812500 2003-12-10 17:48:46.081 127155521260781250 2003-12-10 17:48:46.078 4: 127155521261812500 2003-12-10 17:48:46.181 127155521261875000 2003-12-10 17:48:46.187 5: 127155521262812500 2003-12-10 17:48:46.281 127155521262812500 2003-12-10 17:48:46.281 6: 127155521263812500 2003-12-10 17:48:46.381 127155521263750000 2003-12-10 17:48:46.375 7: 127155521264812500 2003-12-10 17:48:46.481 127155521264843750 2003-12-10 17:48:46.484 8: 127155521265812500 2003-12-10 17:48:46.581 127155521265781250 2003-12-10 17:48:46.578 9: 127155521266812500 2003-12-10 17:48:46.681 127155521266875000 2003-12-10 17:48:46.687 左边是liTimeout,右边是liNow,运行环境:C1.7G,Win2000Server(SP4),误差也太大了吧,KeDelayExecutionThread也是同样效果,问题到底出在哪呢,另外想实现精确的1ms延时有更好的方法吗? |
|
沙发#
发布于:2003-12-11 03:25
又仔细看了一下MSDN,原来“System time is typically updated approximately every ten milliseconds.”,但如何得到精确的时间呢?KeQueryTickCount、KeQueryInterruptTime、KeQueryPerformanceCounter效果好象都不是很好,还有上边那个WaitFor能实现1ms延时吗?没有一个好的时间标尺很难衡量!
|
|
板凳#
发布于:2003-12-11 04:01
刚用KeQueryPerformanceCounter做了个实验,延时1ms,得到如下输出:
050: 127155598950666250 2003-12-10 19:58:15.066 0.002514 ms 051: 127155598950676250 2003-12-10 19:58:15.067 0.001397 ms 052: 127155598950686250 2003-12-10 19:58:15.068 0.001956 ms 053: 127155598950696250 2003-12-10 19:58:15.069 0.001676 ms 054: 127155598950706250 2003-12-10 19:58:15.070 0.001397 ms 055: 127155598950716250 2003-12-10 19:58:15.071 0.001676 ms 056: 127155598950726250 2003-12-10 19:58:15.072 0.001397 ms 057: 127155598950736250 2003-12-10 19:58:15.073 0.001676 ms 058: 127155598950746250 2003-12-10 19:58:15.074 0.001676 ms 059: 127155598950756250 2003-12-10 19:58:15.075 0.001397 ms 060: 127155598950766250 2003-12-10 19:58:15.076 0.001956 ms 061: 127155598950776250 2003-12-10 19:58:15.077 0.001676 ms 062: 127155598950786250 2003-12-10 19:58:15.078 0.966045 ms 063: 127155598950796250 2003-12-10 19:58:15.079 1.905549 ms 064: 127155598950806250 2003-12-10 19:58:15.080 2.929143 ms 065: 127155598950816250 2003-12-10 19:58:15.081 3.919772 ms 066: 127155598950826250 2003-12-10 19:58:15.082 4.872128 ms 067: 127155598950836250 2003-12-10 19:58:15.083 5.864712 ms 068: 127155598950846250 2003-12-10 19:58:15.084 0.001956 ms 069: 127155598950856250 2003-12-10 19:58:15.085 0.001397 ms 070: 127155598950866250 2003-12-10 19:58:15.086 0.001676 ms 071: 127155598950876250 2003-12-10 19:58:15.087 0.001397 ms 072: 127155598950886250 2003-12-10 19:58:15.088 0.001676 ms 073: 127155598950896250 2003-12-10 19:58:15.089 0.001676 ms 074: 127155598950906250 2003-12-10 19:58:15.090 0.001676 ms 075: 127155598950916250 2003-12-10 19:58:15.091 0.001676 ms 076: 127155598950926250 2003-12-10 19:58:15.092 0.001956 ms 077: 127155598950936250 2003-12-10 19:58:15.093 0.001676 ms 078: 127155598950946250 2003-12-10 19:58:15.094 0.953753 ms 079: 127155598950956250 2003-12-10 19:58:15.095 1.971200 ms 080: 127155598950966250 2003-12-10 19:58:15.096 2.909588 ms 081: 127155598950976250 2003-12-10 19:58:15.097 3.913626 ms 082: 127155598950986250 2003-12-10 19:58:15.098 4.875759 ms 最右边那列间隔显然是不能用的,头大! |
|
地板#
发布于:2003-12-11 13:01
NT内核本来就不是实时的,所以别太挑剔了。。。。。
|
|
|
地下室#
发布于:2003-12-11 13:46
看来还是KTIMER+KDPC效果好些
LARGE_INTEGER liDueTime; liDueTime.QuadPart = (LONGLONG)-10000; KeSetTimerEx(&pdx->Timer, liDueTime, (LONG)1, &pdx->Dpc); 基本上还是在2ms左右,间或也有超过4ms的,基本还可以接受,不明白别人us级的延时是如何做的 |
|
论坛版主
![]() |
5楼#
发布于:2003-12-11 14:07
用queryperformancecounter和queryperformancefrequency可以计算出一毫秒需要的tick数,但不知道你怎么定时法,用timer不行吗?我没试过,你可以考虑一下啊,精度不够?
|
|
6楼#
发布于:2003-12-11 16:54
感谢关注!
我想KeQueryPerformanceCounter应该是可信的,精确延时可能不太现实,但ms级应该不算太苛刻吧,相当多的应用要求都比这高,看来单任务、硬件实现确实有其无法比拟的优越性! |
|
7楼#
发布于:2003-12-12 14:58
用户被禁言,该主题自动屏蔽! |
|
8楼#
发布于:2003-12-12 19:13
您是说微秒级的延时?!
|
|