如何在Windows上每毫秒或更多时间做某些事情

这个问题不是关于在Windows(XP或更高版本)上准确计时的事情,而是通过回调或中断非常快速地做出某些事情。

我需要每1毫秒定期做一次,或者最好每100毫秒。 我需要做的是以这个速率驱动一些分布式硬件(以太网),以便向网络输出稳定的数据包流,并使该数据流看起来像常规和同步一样。 但是,如果问题可以从(以太网)设备中分离出来,那么知道一般答案是很好的。

在你说“甚至不考虑使用Windows !!!!”之前,稍微谈一下。 并非所有的实时系统都有相同的需求。 大多数情况下,歌曲和视频在Windows上可以播放,尽管平均每10-16ms左右需要处理音频或图像块。 通过适当的缓冲,Windows可以具有其可变延迟,但是硬件可以广泛地避免它们,并且保持稳定的同步事件流发生。 即便如此,我们大多数人都容忍偶尔出现的故障。 我的应用程序就是这样 - 可能相当宽容。

对我来说,昂贵的选择是将我的整个应用程序移植到Linux上。 但是Linux只是在同一个硬件上运行的不同软件,所以我的强烈偏好是编写一些更好的软件,并坚持使用Windows。 我有能力消除所有竞争的硬件和软件(没有互联网或其他网络访问,没有其他应用程序运行等)的奢侈。 我有没有希望使用Windows来做到这一点? 我会遇到什么限制?

我知道我的目标硬件有一个高性能事件定时器,并且这个定时器可以被编程为中断,但是没有驱动程序。 我可以写一个吗? 那里有有用的例子吗? 我还没有找到。 这会干扰QueryPerformanceCounter吗? 我将要使用以太网设备的事实意味着,如果我明智地使用select(),这一切都变得简单了吗?

欢迎指向有用的文章 - 我已经找到了几十篇关于如何获得准确时间的概述,但还没有关于如何做这样的事情,而不是使用什么等于忙碌的等待。 有没有办法避免忙碌的等待? 是否有内核模式或设备驱动程序选项?


你应该考虑看多媒体计时器。 这些计时器是用于您正在查看的那种分辨率。

在这里看看MSDN。


我是通过使用QueryPerformanceCounter使用DirectX 9来完成的,但您至少需要一个内核,因为任务切换会让您QueryPerformanceCounter

对于你可以看看的网络比较好的比较

http://www.geisswerks.com/ryan/FAQS/timing.html


如果遇到定时器粒度问题,我会建议使用带有旋转循环的旧版Sleep()。 本质上,代码应该像这样做:

void PrecisionSleep(uint64 microSec)
{
    uint64 start_time;

    start_time = GetCurrentTime(); // assuming GetCurrentTime() returns microsecs

    // Calculate number of 10ms intervals using standard OS sleep.
    Sleep(10*(microSec/10000)); // assuming Sleep() takes millisecs as argument

    // Spin loop to spend the rest of the time in
    while(GetCurrentTime() - start_time < microSec)
    {}
}

这样,您将拥有高精度的睡眠,如果它们中的很多大于调度粒度(假定为10毫秒),那么它们不会对您的CPU造成太大的影响。 您可以在循环中发送数据包,同时使用高精度睡眠来计时。

音频在大多数系统上正常工作的原因是音频设备有自己的时钟。 您只需将音频数据缓冲到它,并且它负责播放它,并在缓冲区为空时中断程序。 实际上,如果播放引擎依赖CPU时钟,音频卡时钟和CPU时钟之间的时间偏差可能会导致问题。

编辑:你可以通过使用一个线程使用锁定保护最小堆的定时条目(堆比较完成时间戳),然后你可以回调()或SetEvent() PrecisionSleep()到下一个时间戳完成。

链接地址: http://www.djcxy.com/p/54205.html

上一篇: How to do something every millisecond or better on Windows

下一篇: is there a scalaTest mechanism similar to TestNg dependsOnMethods annotation