【问题标题】:Stable cycle time稳定的循环时间
【发布时间】:2017-07-06 05:02:13
【问题描述】:

我正在尝试执行具有稳定循环时间(例如 20 毫秒)的方法。我目前的方法是使用std::thread 创建一个线程。在这个线程中,我执行以下操作(伪代码):

while(true)
{
  tStart = GetCurrentTime();
  ExecuteMethod();
  tEnd = GetCurrentTime();

  actualCycleTime = tEnd - tStart;
  SleepFor(DesiredCycleTime - actualCycleTime);
}

对于时间测量和睡眠,我使用std::chronostd::steady_clockstd::thread::sleep_for)。

问题是我的循环没有以预期的稳定 20 毫秒运行。相反,我的循环时间在 20 到 60 毫秒之间。我的猜测是这是由 Windows 调度程序引起的。

有没有更好的方法来实现稳定的周期时间(忙等待等)?

【问题讨论】:

标签: c++ winapi stl


【解决方案1】:

您可以使用计时器事件。如果您需要一个非常稳定的时钟,则需要将优先级提高到最大值。此代码将为您提供用户模式应用程序的最佳性能。为了清楚起见,我省略了通常的错误检查,但我已经标记了应该检查的调用。如有疑问,请咨询 MSDN。

Windows 计时器分辨率仅限于 Windows 用于在线程之间切换的全局时间片。在现代 CPU 上,该值通常为 2-5ms。在较旧的 CPU 上,此值为 10-15 毫秒。您可以控制此全局设置 通过调用 timeBeginPeriod()。这会影响中断的精度。

// use this event to exit the loop, by calling SetEvent(hExitEvent).
HANDLE hExitEvent = CreateEvent(NULL, NULL, FALSE, NULL);  

void RealTimeLoop()
{
    // You may want to raise the process priority...
    HANDLE hProcess = GetCurrentProcess();                       // never fails
    SetPriorityClass(hProcess, REALTIME_PRIORITY_CLASS);

    // setting the priority is critical.
    HANDLE hThread = GetCurrentThread();                         // never fails
    SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);   // could fail

    timeBeginPeriod(1);                                          // could fail

    HANDLE hTimer = CreateWaitableTimer(NULL, FALSE, NULL);      // could fail

    // could also set a call back here, but I've never tried it.
    LARGE_INTEGER dueTime = {};
    SetWaitableTimer(hTimer, &dueTime, 20, NULL, NULL, FALSE);   // could fail

    HANDLE ah[2] = { hExitEvent, hTimer };
    bool exitLoop = false;

    while(!exitLoop)
    {
        switch (WaitForMultipleObjects(2, ah, FALSE, INFINITE))
        {
            default:  // error would arrive here 
            case 0:  exitLoop = true; break;
            case 1:  ExecuteMethod(); break;
        }
   }
   timeEndPeriod(1);
   CloseHandle(hTimer);
   CloseHandle(hThread);
   CloseHandle(hProcess);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 2011-02-02
    • 2012-01-26
    • 1970-01-01
    • 2019-03-21
    • 1970-01-01
    相关资源
    最近更新 更多