【问题标题】:WIN API timer for console application控制台应用程序的 WIN API 计时器
【发布时间】:2013-11-13 16:26:21
【问题描述】:

我有一个用 C++ 编写的控制台 Windows 应用程序,它为某些分步游戏的给定级别找到解决方案(或证明不存在解决方案)。我们称它为“求解器”。此应用程序从 Python 脚本循环启动,适用于所有游戏关卡。有些关卡太难了,需要几个小时甚至几天才能解决。

如果我的应用程序可以输出一些字符串,例如“太难级别”并退出,从而允许 Python 脚本进入下一个级别,如果它未能找到解决方案(或证明其不存在),这是可以接受的比如说 30 分钟。

如何在求解器启动 30 秒后中断它?从技术上讲,求解算法只是一个从int main() 调用的递归过程。

我正在考虑创建辅助线程,该线程将在启动后 30 分钟唤醒并设置一些布尔标志。并且主要(解决)线程会定期检查这个标志。

这可行,但没有更简单更优雅的解决方案吗?

【问题讨论】:

  • 您还可以使用std::chrono::system_clock::now() 捕获开始时间并检查循环中的时差。但是,您提出的解决方案可能更经济。不过,您必须注意布尔值的同步。
  • @DmitryLedentsov 与其说是同步,不如说是错误缓存的危险。任何种族都是良性的。需要一个原子。

标签: c++ multithreading winapi timer


【解决方案1】:

由于您的代码不是以消息驱动的方式运行,我不确定这里是否需要计时器,甚至是否合适。您可能是对的,您需要您的主计算线程定期检查它是否需要超时。在这种情况下,不需要另一个带有计时器的线程。只要记住计算开始的时间,每次检查超时,看看是否已经过了 30 秒。

在伪代码中:

startTime = now();
while (doingCalc)
{
    DoSomeMoreCalc();
    if (now() - startTime) > 30.0)
        timeOut();
}

【讨论】:

  • 这可能是最好的解决方案;因为你正忙着循环,所以不需要计时器,只需检查时间作为循环的一部分。
【解决方案2】:

不确定这是否可行,但值得一试..

#include <windows.h>
#include <iostream>
#include <thread>

UINT_PTR ID = NULL;

void __stdcall OnTimerEvent(HWND hwnd, UINT msg, UINT_PTR id, DWORD dwTime)
{
    std::cout<<"HERE\n";
    KillTimer(NULL, ID);
}

int main()
{
    std::thread([] {
        MSG msg = {0};
        ID = SetTimer(NULL, 0, 3000, &OnTimerEvent); //3 second timer.

        while(GetMessage(&msg, NULL, 0, 0))
        {
            DispatchMessage(&msg);
        }

        KillTimer(NULL, ID);
    }).detach();

    std::cin.get();
}

【讨论】:

  • -1 “控制台应用程序”DispatchMessage 重叠为零。
  • 我认为您看不懂..“控制台应用程序的 WinAPI 计时器”。这正是我给 OP 的。再看看标签。它被标记为 Winapi、多线程、计时器。我的解决方案不是最好的,但它具备所有这些并且有效。
  • 提问者没有要求演示如何在线程中调用SetTimer 的程序。我想如果有人看不懂,那就是你。仔细阅读问题。尝试用更多的文字和更少的代码来回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-03
  • 2010-09-05
  • 1970-01-01
  • 2013-08-03
  • 2011-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多