我在我的应用程序 (C# .NET) 中使用多媒体计时器来提高计时器的准确性并实现 1 毫秒的计时器频率。到目前为止,我的应用程序一直运行良好,直到最近它开始表现奇怪。我试图了解我的应用程序出了什么问题。以下是采取的步骤
- 定时器频率设置为 1 ms,每 1ms 调用一次回调
- 有 4 个线程,每个线程创建自己的计时器对象。它们都设置为 1ms 后调用回调。这些是单独的实例,不共享。
- 旧代码执行时间约为 0.3 毫秒。在下一步之前这一切都运行良好。
- 应用程序代码已更改。计时器回调函数现在执行大约需要 1.2 毫秒。这显然是一个问题。 (稍后我将致力于优化代码。但现在我只想了解多媒体计时器的行为)
- 只有第一个线程正在调用计时器回调,而对于其他线程,回调仅被调用两次或三次,之后回调将不再被调用。
- 看起来对于其他线程,计时器甚至被错过(?)并且它无法赶上。 (它错过了每次中断)。
您能解释一下计时器对象的行为吗?由于它是单个进程,所有线程实际上都指向同一个计时器对象吗?
为什么其他线程不调用计时器回调?
多媒体计时器的最大分辨率为 1ms。这会导致可编程中断控制器(在硬件上)每 1ms 触发一次。如果您启动 4 个线程,它们都创建具有 1 毫秒计时的计时器,这并不意味着您每毫秒会收到多次事件。
我鼓励您阅读为什么多媒体计时器 API (timeSetEvent) 不如我预期的那么准确? http://blogs.msdn.com/b/mediasdkstuff/archive/2009/07/02/why-are-the-multimedia-timer-apis-timesetevent-not-as-accurate-as-i-would-expect.aspxMSDN 上的博客文章。
一些适用于此的引言(强调我的):
MM 定时器 API 允许开发人员重新编程可编程
机器上的中断控制器(PIC)。您可以指定新的
计时器分辨率。通常,我们会将其设置为 1 毫秒。这
是定时器的最大分辨率。我们无法达到亚毫秒级
准确性。PIC 重新编程的效果是导致
操作系统更频繁地唤醒。这增加了我们的机会
应用程序将在我们执行操作时由操作系统通知
指定的。我说“增加机会”是因为我们仍然不能
保证我们确实会收到通知,即使
当我们告诉它时,操作系统就会启动。
And:
请记住,PIC 用于唤醒操作系统,以便它可以决定
接下来应该运行哪个线程。操作系统使用一些非常复杂的规则来
确定接下来哪个线程将占用处理器。其中两个
操作系统查看以确定是否应该运行线程或
线程优先级和线程量子不是。
因此,即使您将分辨率降低到最大值 1 毫秒,也不能保证您的线程将被选择执行其工作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)