[英]Understanding the strange behavior of multimedia timer
I am using Multimedia timers in my application (C# .NET) to increase accuracy of my timer and to achieve 1 ms timer frequency.我在我的应用程序 (C# .NET) 中使用多媒体计时器来提高我的计时器的准确性并实现 1 ms 计时器频率。 My application had been working great so far until recently it started behaving strangely.
到目前为止,我的应用程序一直运行良好,直到最近它开始出现奇怪的行为。 I am trying to understand what is wrong with my application.
我试图了解我的应用程序有什么问题。 Below are the steps taken
以下是采取的步骤
Could you please explain me the behavior of the timer objects.你能解释一下计时器对象的行为吗? Are all the threads actually pointing to same timer object since its a single process?
由于它是单个进程,所有线程实际上都指向同一个计时器对象吗? Why are other threads not calling the timer callback?
为什么其他线程不调用定时器回调?
The maximum resolution for the Multimedia timer is 1ms.多媒体定时器的最大分辨率为 1ms。 This causes the programmable interrupt controller (on the hardware) to fire every 1ms.
这会导致可编程中断控制器(在硬件上)每 1 毫秒触发一次。 If you fire up 4 threads that all create timers which have 1ms timings that does not mean you will get events more than once per millisecond.
如果您启动 4 个线程,它们都创建了具有 1 毫秒计时的计时器,这并不意味着您每毫秒将获得多次事件。
I encourage you to read the Why are the Multimedia Timer APIs (timeSetEvent) not as accurate as I would expect?我鼓励您阅读为什么多媒体计时器 API (timeSetEvent) 没有我预期的那么准确? blog post on MSDN.
MSDN 上的博客文章。
Some quotes that are applicable here (emphasis mine):一些适用于此的引用(强调我的):
The MM Timer APIs allow the developer to reprogram the Programmable Interrupt Controller (PIC) on the machine.
MM 定时器 API 允许开发人员重新编程机器上的可编程中断控制器 (PIC)。 You can specify the new timer resolution.
您可以指定新的计时器分辨率。 Typically, we will set this to 1 millisecond.
通常,我们会将其设置为 1 毫秒。 This is the maximum resolution of the timer.
这是定时器的最大分辨率。 We can't get sub-millisecond accuracy.
我们无法获得亚毫秒级的准确度。 The effect of this reprogramming of the PIC is to cause the OS to wake up more often.
这种对 PIC 重新编程的效果是导致操作系统更频繁地唤醒。 This increases the chances that our application will be notified by the operating system at the time we specified.
这增加了操作系统在我们指定的时间通知我们的应用程序的机会。 I say, “Increases the chances” because we still can't guarantee that we will actually receive the notification even though the OS work up when we told it.
我说,“增加机会”是因为我们仍然不能保证我们真的会收到通知,即使操作系统在我们告诉它时工作。
And:并且:
Remember that the PIC is used to wake up the OS so that it can decide what thread should be run next.
请记住,PIC 用于唤醒操作系统,以便它可以决定接下来应该运行哪个线程。 The OS uses some very complex rules to determine what thread gets to occupy the processor next.
操作系统使用一些非常复杂的规则来确定接下来哪个线程占用处理器。 Two of the things that the OS looks at to determine if it should run a thread or not are thread priority and thread quantum.
操作系统查看以确定是否应该运行线程的两件事是线程优先级和线程量子。
So, even if you put the resolution down to the maximum of 1ms, you are not guaranteed that your thread will be the one chosen to do its work.因此,即使您将分辨率降低到 1 毫秒的最大值,也不能保证您的线程将成为被选中执行其工作的线程。
I suppose that you use a system timer that runs callbacks on a single dedicated thread.我想你使用了一个在单个专用线程上运行回调的系统计时器。
Then you set the system interval to 1 ms.然后将系统间隔设置为 1 毫秒。 And before your change the callback takes 0.3 ms to complete, so the callbacks of the 4 threads take 4 * 0.3 = 1.2 ms to complete.
在您更改之前,回调需要 0.3 毫秒才能完成,因此 4 个线程的回调需要 4 * 0.3 = 1.2 毫秒才能完成。 So they manage to complete on 1-2 time intervals, and can all start again after that.
所以他们设法在 1-2 个时间间隔内完成,之后都可以重新开始。
But after your change each callback takes 1.2 ms itself.但是在您更改后,每个回调本身需要 1.2 毫秒。 So we have requests to run callbacks from the threads 2-4 and another request from thread 1 (because the time interval ran out).
所以我们有从线程 2-4 运行回调的请求和来自线程 1 的另一个请求(因为时间间隔用完了)。 After that it depends on the timer used, which request it will serve.
之后,它取决于使用的计时器,它将服务哪个请求。 It turns out, that the one from the first thread.
事实证明,来自第一个线程的那个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.