【问题标题】:SetLocalTime causing PC to lag, how can I optimize it?SetLocalTime 导致 PC 卡顿,如何优化?
【发布时间】:2021-01-11 23:55:31
【问题描述】:

我想创建一个可以减慢 Windows 时间的程序。我将为此使用SetLocalTime()。但是,当我打开程序时,我的电脑开始出现微卡顿,游戏性能下降,即使该进程几乎没有使用任何 CPU。

#include <iostream>
#include "Windows.h"
#include <thread> 
#include <chrono>
using namespace std;

SYSTEMTIME st;
WORD hour;
WORD minute;
WORD second = 0;

int main()
{
    GetLocalTime(&st);
    hour = st.wHour;
    minute = st.wMinute;
    second = st.wSecond;

    for (;;)
    {
        for (int i = 0; i < 4; i++)
        {
            this_thread::sleep_for(chrono::milliseconds(500));
            st.wHour = hour;
            st.wMinute = minute;
            st.wSecond = second;
            SetLocalTime(&st);
        }
        second++;
        if (second == 60)
        {
            second = 0;
            minute++;
        }
        if (minute == 60)
        {
            minute = 0;
            hour++;
        }
    }
}

【问题讨论】:

  • 如果您通过更改 Windows 时间来减慢时间,那么每个使用系统时钟进行计时的程序不会也开始变慢吗?你想达到什么目的?
  • 我正在尝试实现一个让 windows 时间变慢的程序,因为这将帮助我对使用 windows 时间的应用程序进行时间调整
  • 这可能无法修复,但我的建议是调整值,看看它是否会增加或减少口吃。
  • @DorukGez "这将帮助我对使用 Windows 时间的应用程序进行时间调整" - 那么为什么不直接挂钩该特定应用程序,而不是操纵操作系统本身呢?挂钩 GetLocalTime()GetSystemTime() 和其他相关 API,让它们返回任何你想要的。
  • 它不适用于这个应用程序也许这意味着它不会起作用。可能问题是目标应用程序有代码来处理 WM_TIMECHANGE 消息,而此代码会导致卡顿,因为您在短时间内更改了很多次。

标签: c++ performance time


【解决方案1】:

如果更改系统时钟,所有使用它进行计时的程序也会变慢。

从您的 cmets 中,我可以了解到您希望对使用时间的应用程序进行时间缩放。到目前为止,您还没有得到更具体的信息,因此我只能提出一般方法。

创建一个时间管理器类,当您启动应用程序时,它会获取当前系统时间并将其存储为应用程序的基本时间。不要使用 GetLocalTime() 或 GetSystemTime(),而是在您的类中创建一个方法,该方法将根据时间膨胀因子返回当前时间。

class TimeManager
{
  private:
    SYSTEMTIME _BaseTime;
    double _TimeDilatation;
  public:
    TimeManager();
    void SetTimeDilatation(double timeDilatation);
    void GetTime(LPSYSTEMTIME lpSystemTime);
};

// Constructor will get the current local time.
TimeManager::TimeManager()
{
  GetLocalTime(&_BaseTime);
}

// Sets the time dilatation factor.
// 0.0 to 0.9 time will slow down
// 1.0 normal flow of time
// 1.1 to max double, time will go faster
void TimeManager::SetTimeDilatation(double timeDilatation)
{
  _TimeDilatation = timeDilatation;
}

// Get the current time taking into account time dilatation
void TimeManager::GetTime(LPSYSTEMTIME lpSystemTime)
{
  SYSTEMTIME resultingTime;
  SYSTEMTIME realTime;

  FILETIME ftime;
  ULARGE_INTEGER uliTime;
  __int64 lowerValue, higherValue, result;

  // Get the current local time
  GetLocalTime(&realTime);

  // Translate the base time into a large integer for subtraction
  SystemTimeToFileTime(&_BaseTime, &ftime);
  uliTime.LowPart = ftime.dwLowDateTime;
  uliTime.HighPart = ftime.dwHighDateTime;
  lowerValue = uliTime.QuadPart;

  // Translate the current time into a large integer for subtraction
  SystemTimeToFileTime(&realTime, &ftime);
  uliTime.LowPart = ftime.dwLowDateTime;
  uliTime.HighPart = ftime.dwHighDateTime;
  higherValue = uliTime.QuadPart;

  // Get the time difference and multiply the dilatation factor
  result = (higherValue - lowerValue) * _TimeDilatation;
  // Apply the difference to the base time value
  result = lowerValue + result;

  // Convert the new time back into a SYSTEMTIME value
  uliTime.QuadPart = result;
  ftime.dwLowDateTime = uliTime.LowPart;
  ftime.dwHighDateTime = uliTime.HighPart;
  FileTimeToSystemTime(&ftime,&resultingTime);

  // Assign it to the pointer passed in parameter, and feel like a Time Lord.
  *lpSystemTime = resultingTime;
}

int main()
{
  TimeManager TM;
  TM.SetTimeDilatation(0.75f); // the time will pass 75% slower

  for (;;)
  {
    SYSTEMTIME before, after;

    TM.GetTime(&before);
    
    // Do something that should take exactly one minute to process.

    TM.GetTime(&after);

    // Inspect the value of before and after, you'll see
    // that only 45 secondes has passed
  }
}

请注意,将您推向正确的方向是一个总体思路。我还没有编译那个代码,所以可能有一个或五个错误。随时指出他们,我会修复我的帖子。我只是不想太具体,因为您的问题有点宽泛;根据您的用例,此代码可能会或可能不会帮助您。但这通常是您在不影响系统时间的情况下减慢时间的方式。

【讨论】:

  • 感谢您的出色回答,我目前确实收到了一个错误,即 Severity Code Description Project File Line Suppression State Warning C4717 'TimeManager::GetLocalTime': recursive on all control paths, function will cause runtime stack overflow 可悲的是,我是编程的初学者,无法弄清楚如何自己修复它
  • 天哪,是的,对不起,我将方法命名为与 API 调用相同。我以为这会有助于理解,但这真的不好。我会编辑。
  • 更改 TimeManager::GetTime 和 void TimeManager::GetTime 和 void TimeManager::SetTimeDilation 修复声明不兼容
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多