gpt4 book ai didi

c++ - Win32 API 定时器

转载 作者:太空狗 更新时间:2023-10-29 23:29:20 24 4
gpt4 key购买 nike

我正在使用系统计时器(clock() 函数,请参阅 time.h)为一些串行和 USB 通信计时。我所需要的只是大约 1 毫秒的精度。我注意到的第一件事是个别时间可能超过(正负)10 毫秒。为许多较小的事件计时会导致事件发生时计时不准确。聚合时间稍微好一些。在 MSDN 等上扎了根之后,我偶然发现了 Windows 多媒体库中的计时器(timeGetTime(),请参阅 MMSystem.h)。这要好得多,准确度达到 1 毫秒级别。

然后奇怪的事情接踵而至,在最初完美无瑕地工作了几天之后(可爱的日志和有用的计时)一切都变得梨形,因为这个 API 也开始显示这种奇怪的粒度(而不是一堆需要 3ms、2ms、3ms、2ms 的小通信消息, 3ms 等。结果显示为 0ms、0ms、0ms、0ms、15ms 等。重新启动 PC 恢复了正常精度,但在某个不确定的时间(大约一个小时后)异常返回。

任何人都对如何在 Windows XP(32 位专业版,使用 Visual Studio 2008)上获得这种级别的计时精度有任何想法或建议。

我的小计时课:

class TMMTimer
{
public:
TMMTimer( unsigned long msec);
TMMTimer();

void Clear() { is_set = false; }
void Set( unsigned long msec=0);

bool Expired();
unsigned long Elapsed();

private:
unsigned long when;
int roll_over;
bool is_set;
};



/** Main constructor.
*/
TMMTimer::TMMTimer()
{
is_set = false;
}




/** Main constructor.
*/
TMMTimer::TMMTimer( unsigned long msec)
{
Set( msec);
}




/** Set the timer.
*
* @note This sets the timer to some point in the future.
* Because the timer can wrap around the function sets a
* rollover flag for this condition which is checked by the
* Expired member function.
*/
void TMMTimer::Set( unsigned long msec /*=0*/)
{
unsigned long now = timeGetTime(); // System millisecond counter.

when = now + msec;

if (when < now)
roll_over = 1;
else
roll_over = 0;

is_set = true;
}




/** Check if timer expired.
*
* @return Returns true if expired, else false.
*
* @note Also returns true if timer was never set. Note that this
* function can handle the situation when the system timer
* rolls over (approx every 47.9 days).
*/
bool TMMTimer::Expired()
{
if (!is_set)
return true;

unsigned long now = timeGetTime(); // System millisecond counter.

if (now > when)
{
if (!roll_over)
{
is_set = false;
return true;
}
}
else
{
if (roll_over)
roll_over = false;
}

return false;
}




/** Returns time elapsed since timer expired.
*
* @return Time in milliseconds, 0 if timer was never set.
*/
unsigned long TMMTimer::Elapsed()
{
if (!is_set)
return 0;

return timeGetTime()-when;
}

最佳答案

您是否调用 timeBeginPeriod(1); 将多媒体分辨率设置为 1 毫秒?多媒体计时器分辨率是系统全局的,所以如果你没有自己设置它,很可能你是在其他东西调用它之后开始的,然后当那个叫做 timeEndPeriod() 的东西时,分辨率回到系统默认值(如果没记错的话,通常是 10 毫秒)。

其他人建议使用 QueryPerformanceCounter()。这确实具有更高的分辨率,但您仍然需要小心。根据所涉及的内核,它可以/将使用 x86 RDTSC 函数,这是一个 64 位指令周期计数器。无论好坏,在时钟速率变化的 CPU 上(开始于笔记本电脑,但现在几乎无处不在),时钟计数和挂钟时间之间的关系随时钟速度而变化。如果内存可用,如果您在假设有多个物理处理器(不仅仅是多个内核)的情况下强制安装 Windows,您将获得一个内核,其中 QueryPerformanceCounter() 将读取主板的 1.024 MHz时钟代替。与 CPU 时钟相比,这会降低分辨率,但至少速度是恒定的(如果您只需要 1 毫秒的分辨率,无论如何它应该绰绰有余)。

关于c++ - Win32 API 定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2274873/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com