我有一台机器,它使用 NTP 客户端来同步互联网时间,因此它的系统时钟应该相当准确。

我正在开发一个应用程序,它实时记录数据、处理数据然后传递它。我现在想做的是每 N 毫秒输出与系统时钟一致的数据。例如,如果我想做 20 毫秒的间隔,我的输出应该是这样的:

13:15:05:000
13:15:05:020
13:15:05:040
13:15:05:060

我已经看到了使用秒表类的建议,但它只测量时间跨度,而不是寻找特定的时间戳。执行此操作的代码在它自己的线程中运行,因此如果我需要执行一些相对阻塞的调用,那么这应该是一个问题。

任何关于如何合理地实现这一目标(接近或优于 1 毫秒的精度就更好了)的建议将非常感激。

有帮助吗?

解决方案

不知道它起着如何用C ++ / CLR,但你可能想看看的多媒体计时器,点击 Windows不是真正实时的,但这是接近,因为它得到

其他提示

您可以得到一个相当准确的时间标记出timeGetTime()时,你缩短了时间。你只需要一些工作来获取其返回值转换为一个时钟时间。此示例C#代码所示的方法:

using System;
using System.Runtime.InteropServices;

class Program {
    static void Main(string[] args) {
        timeBeginPeriod(1);
        uint tick0 = timeGetTime();
        var startDate = DateTime.Now;
        uint tick1 = tick0;
        for (int ix = 0; ix < 20; ++ix) {
            uint tick2 = 0;
            do {  // Burn 20 msec
                tick2 = timeGetTime();
            } while (tick2 - tick1 < 20);
            var currDate = startDate.Add(new TimeSpan((tick2 - tick0) * 10000));
            Console.WriteLine(currDate.ToString("HH:mm:ss:ffff"));
            tick1 = tick2;
        }
        timeEndPeriod(1);
        Console.ReadLine();
    }
    [DllImport("winmm.dll")]
    private static extern int timeBeginPeriod(int period);
    [DllImport("winmm.dll")]
    private static extern int timeEndPeriod(int period);
    [DllImport("winmm.dll")]
    private static extern uint timeGetTime();
}

在第二个想法,这仅仅是测量。为了得到定期执行的操作,你将不得不使用的timeSetEvent()。只要你使用timeBeginPeriod(),就可以得到回调周期非常接近1毫秒。一个精密的是,当先前的回调迟到了任何原因,它将会自动补偿。

最好的选择是使用内联汇编并将这段代码编写为设备驱动程序。

那样:

  • 您可以控制指令数量
  • 您的应用程序将具有执行优先权

最后你不能保证你想要的,因为操作系统必须从其他进程运行荣誉的请求,这意味着别的东西可以永远忙正是你希望你的程序在运行的时刻。例如 - 但是你可以使用timeBeginPeriod,使之更可能是你的过程可以及时切换到,也许是狡猾与您如何等待迭代之间改善的问题。睡大多数但不是所有的时间,然后用一个忙环为剩余部分。

尝试在两个线程这样做。在一个线程中,使用类似查询在一个循环高精度的定时器。当你发现一个时间戳对齐(或合理地接近)20ms的边界,将信号发送到您的日志输出线与时间戳一起使用。你的日志输出线程只会等待信号,然后抓住传入的时间戳和任何需要的输出。保持两个单独的线程将确保您的日志输出线程不与定时器干扰(这基本上是模仿一个硬件定时器中断,这将是我会做一个嵌入式平台上的样子)。

CreateWaitableTimer / SetWaitableTimer和高优先级的线程应精确到1ms左右。我不知道为什么在您的示例输出的毫秒字段具有四位,最大值为999(因为1000毫秒= 1秒)。

既然如你所说,这并不一定是完美的,也有一些事情可以做。

据我所知,不存在一个计时器,与特定的时间同步。所以,你必须计算你的下一个时间,安排在特定时间的计时器。如果你的计时器只有增量的支持,那么,很容易计算,但因为你可以很容易断的时间之间的CPU被踢增加了更多的错误,你计算你三角洲和定时器输入到内核的时间。

前面已经指出的那样,Windows不是一个实时操作系统。所以,你必须假设,即使你安排一个计时器在到下车“:0010”,你的代码可能甚至不执行,直到那个时候好后(例如“:0540”)。只要你正确地处理这些问题,事情就会“OK”。

20ms的是大约Windows上的时间片的长度。有没有办法打1ms的那种定时在windows可靠没有某种RT的增加像银泰。在windows正确,我认为你的选择是WaitForSingleObject的,SleepEx和繁忙的循环。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top