Windows MSG::time晚于timeGetTime

Windows MSG::time晚于timeGetTime,windows,time,message-queue,Windows,Time,Message Queue,在注意到代码中的事件存在一些定时重复之后,我将问题一直归结到我的Windows消息循环 基本上,除非我在做一些奇怪的事情,否则我会经历这种行为:- MSG message; while (PeekMessage(&message, _applicationWindow.Handle, 0, 0, PM_REMOVE)) { int timestamp = timeGetTime(); bool strange = message.time > timestamp;

在注意到代码中的事件存在一些定时重复之后,我将问题一直归结到我的Windows消息循环

基本上,除非我在做一些奇怪的事情,否则我会经历这种行为:-

MSG message;

while (PeekMessage(&message, _applicationWindow.Handle, 0, 0, PM_REMOVE))
{
    int timestamp = timeGetTime();
    bool strange = message.time > timestamp; //strange == true!!!

    TranslateMessage(&message);
    DispatchMessage(&message);
}
我能得出的唯一合理结论是
MSG::time
使用了不同的计时机制,然后
timeGetTime()
,因此可以自由地产生不同的结果。
是这样,还是我遗漏了一些基本的东西?

这可能是一个已签名未签名的问题吗?您正在比较有符号整数(时间戳)和无符号DWORD(msg.time)

此外,时钟每40天一次——当这种情况发生时,奇怪的事情很可能是真的


顺便说一句,如果你没有很好的理由使用timeGetTime,你可以在这里使用GetTickCount——这样可以节省你引入winmm的时间

下面的代码显示了您应该如何使用时间-您永远不应该直接比较时间,因为时钟包装会弄乱时间。相反,您应该总是从当前时间中减去开始时间,然后查看间隔

// This is roughly equivalent code, however strange should never be true
// in this code
DWORD timestamp = GetTickCount();
bool strange = (timestamp - msg.time < 0);
//这是大致相同的代码,但奇怪的是,这永远不会是真的
//在此代码中
DWORD timestamp=GetTickCount();
布尔奇怪=(时间戳-msg.time<0);

这可能是一个已签名的问题吗?您正在比较有符号整数(时间戳)和无符号DWORD(msg.time)

此外,时钟每40天一次——当这种情况发生时,奇怪的事情很可能是真的


顺便说一句,如果你没有很好的理由使用timeGetTime,你可以在这里使用GetTickCount——这样可以节省你引入winmm的时间

下面的代码显示了您应该如何使用时间-您永远不应该直接比较时间,因为时钟包装会弄乱时间。相反,您应该总是从当前时间中减去开始时间,然后查看间隔

// This is roughly equivalent code, however strange should never be true
// in this code
DWORD timestamp = GetTickCount();
bool strange = (timestamp - msg.time < 0);
//这是大致相同的代码,但奇怪的是,这永远不会是真的
//在此代码中
DWORD timestamp=GetTickCount();
布尔奇怪=(时间戳-msg.time<0);

我不认为期望或依赖从不同来源返回的时间戳绝对值之间的任何特定关系是明智的。一方面,多媒体计时器可能与系统计时器具有不同的分辨率。另一方面,多媒体计时器在单独的线程中运行,因此您可能会遇到同步问题。(我不知道是否每个CPU都有自己独立的计时功能。)此外,如果您正在运行任何类型的时间同步服务,它可能会对您的本地时钟进行自己的调整,并影响您看到的时间戳。

我认为不建议期望或依赖从不同来源返回的时间戳绝对值之间的任何特定关系。一方面,多媒体计时器可能与系统计时器具有不同的分辨率。另一方面,多媒体计时器在单独的线程中运行,因此您可能会遇到同步问题。(我不知道是否每个CPU都有自己独立的时钟计数。)此外,如果您运行任何类型的时间同步服务,它可能会对您的本地时钟进行自己的调整,并影响您看到的时间戳。

您是否有机会运行AMD双核?存在这样一个问题:由于每个内核都有一个单独的计时器,并且可以以不同的速度运行,因此计时器可能会彼此分离。例如,这可以表现为

在使用GetTickCount()测量不同线程中的超时时,我遇到了类似的问题


安装(IIRC)以解决此问题。

您是否有机会运行AMD双核?存在这样一个问题:由于每个内核都有一个单独的计时器,并且可以以不同的速度运行,因此计时器可能会彼此分离。例如,这可以表现为

在使用GetTickCount()测量不同线程中的超时时,我遇到了类似的问题


安装(IIRC)以解决此问题。

MSG.time基于GetTickCount(),而timeGetTime()使用多媒体计时器,它完全独立于GetTickCount()。看到一个计时器在另一个计时器之前“滴答”一点也不奇怪。

MSG.time基于GetTickCount(),而timeGetTime()使用多媒体计时器,它完全独立于GetTickCount()。看到一个计时器在另一个计时器之前“滴答”一点也不奇怪。

“顺便说一句,如果你没有很好的理由使用timeGetTime,你可以在这里使用GetTickCount,这样可以节省你带来winmm的时间。”非常好的提示谢谢。我想GetTickCount将是更多的腿部工作才能被包括在内!我按照我的想法检查了类型,但是值都是正值并且在范围内。Adam-上面的代码仍然是错误的,当系统时钟结束时,会以意外的方式失败。这些值显然都是正数,因为它们都是无符号的@Stewart,不,即使数字扭曲,也不会失败,因为减法也会结束。“顺便说一句,如果你没有很好的理由使用timeGetTime,你可以在这里使用GetTickCount-它可以节省你带来winmm的时间。”非常好的提示谢谢。我想GetTickCount将是更多的腿部工作才能被包括在内!我按照我的想法检查了类型,但是值都是正值并且在范围内。Adam-上面的代码仍然是错误的,当系统时钟结束时,会以意外的方式失败。这些值显然都是正数,因为它们都是无符号的@Stewart,不,即使数字扭曲,也不会失败,因为减法也会自动换行。MSG::time是消息发布到队列的时间;在发布消息和检索消息之间可能会有一些延迟