C++ 稳定循环时间

C++ 稳定循环时间,c++,winapi,stl,C++,Winapi,Stl,我正在尝试执行一个周期时间稳定的方法,例如20ms。我目前的方法是使用std::thread创建线程。在该线程中,我执行以下伪代码: while(true) { tStart = GetCurrentTime(); ExecuteMethod(); tEnd = GetCurrentTime(); actualCycleTime = tEnd - tStart; SleepFor(DesiredCycleTime - actualCycleTime); } 对于时间测量和

我正在尝试执行一个周期时间稳定的方法,例如20ms。我目前的方法是使用std::thread创建线程。在该线程中,我执行以下伪代码:

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

  actualCycleTime = tEnd - tStart;
  SleepFor(DesiredCycleTime - actualCycleTime);
}
对于时间测量和睡眠,我使用std::chrono std::staid_clock和std::thread::sleep_

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


是否有更好的方法实现稳定的循环时间忙碌等待等?

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

Windows计时器分辨率仅限于Windows用于在线程之间切换的全局时间片。在现代CPU上,该值通常为2-5ms。在较旧的CPU上,此值为10-15ms。您可以控制此全局设置 通过调用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);
}

您使用的是重复的相对计时,在确定实际循环时间和设置所需循环时间之间容易受到赛车条件的影响。您需要一个所需周期时间的外部控制定期触发器。您可能希望查看timeSetEvent在与timeBeginPeriod一起使用时的可靠性。MSDN说它已经过时了,你应该使用它。我没有这方面的经验,所以我不能说它有多可靠或精确。请使用sleep_,直到,例如: