现代高分辨率定时器用于周期性调用

3
在stackoverflow上,已经有很多关于高分辨率定时器的讨论。但显然,解决方案是一个不断变化的目标,最佳实践也在不断变化。
我需要创建一个高分辨率定时器,每10毫秒回调一次,以实现稳定的100Hz。目标平台是Windows 7及更高版本。
这个确切的问题在2009年被提出,但我相信事情可能已经发生了改变。
多媒体定时器似乎是一个很好的解决方案,但MSDN表示它们已经过时,被CreateTimerQueueTimer所取代。但stackoverflow上的其他答案表明,CreateTimerQueue timer并不像timeSetEvent那样精确。
所有答案都一致指出,需要使用timeBeginPeriod将Windows计时器分辨率设置为较低的值。
因此,针对上述目标,在C中采用什么方法是最好的呢?

你需要每10毫秒一个回调函数,但你期望的精度是多少?0.1?1%?还是10%? - mins
你可以使用MinGW和timeb.h,它会给你一个包含毫秒的struct timeb - ForceBru
1
我真的不认为win7在这方面很好,因为它并不是设计成实时操作系统。如果您有非常严格的实时约束条件,请尝试其他实时操作系统,这些操作系统可能提供了大量用于调度和定时的API。 - user3528438
你的问题中提到你使用C语言,为什么要加上C++标签呢?C和C++是不同的编程语言,我在你的问题中没有看到任何与C++相关的内容。 - juhist
@mins 大约0.1毫秒是我所寻求的精度。或者换句话说,误差在正负1%之间。 - tookitonce
1
如果操作系统不是限制条件,我肯定不会使用Win7。事实上,我肯定会选择实时操作系统。但是由于操作系统是一个限制条件,因此我将目标设定为Windows 7。 - tookitonce
2个回答

4

但是MSDN说它们已经被弃用了

当你看到这样的废弃警告时,有能力读懂其中含义是非常重要的。是的,Microsoft希望所有人都停止使用多媒体计时器。它们被严重滥用,并对业务非常不利。但让程序员停止使用它们只是一个美好的愿景,CreateTimerQueueTimer()也不是一种替代方案。

它对业务不利,因为Microsoft希望在移动计算领域具有竞争力。而多媒体计时器则非常不匹配,它们会大大降低电池寿命。大多数使用它们的程序将时钟中断率最大限度地提高到每秒1000次。甚至还有一个后门可以达到2000次。阻止它们这样做非常困难,特别是当它们的竞争对手 免费提供他们的软件时。他们根本没有任何动力解决这个问题,因为这使得他们的移动操作系统看起来很好。而Microsoft不能杀死非常受欢迎的应用程序。

Microsoft也有一个移动操作系统,可以通过WinRT api进行访问。当你使用那些计时器时,在这种淘汰的情况下,你无法通过商店验证程序获得应用的批准。但是它并没有得到很多的使用,他们的客户喜欢继续使用他们的桌面应用程序。
如果您想要100 Hz的更新频率,那么您必须使用timeBeginPeriod()和timeSetEvent(),没有其他方法。避免使用WinRT。由于实际上只比默认值差1.5倍,因此没有明显的原因担心耗电量。设置激光为震荡并使用有效的方法。

感谢对“微软方式”的澄清。我很幸运,因为这是一个控制系统,其本质上必须插入主电源。因此,我很乐意消耗更多的瓦特数来实现结果。 - tookitonce

0

你愿意在使用过程中消耗CPU吗?在繁忙的循环中调用QueryPerformanceCounter()。你将获得微秒级精度,但会对电池寿命产生适当的不良影响。你还可以通过将进程优先级类别提高到REALTIME_PRIORITY_CLASS并将工作线程的优先级提高到THREAD_PRIORITY_TIME_CRITICAL(或稍低一些)来进一步提高性能。当然,这样做也会带来负面后果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接