如何将Windows Timer设置为后台线程运行

4
问题:如何让计时器在后台滴答声?也就是创建计时器线程的线程可以在时钟滴答声的同时做其他事情。
尝试: -使用 _beginthreadex() --> 看起来有竞争条件。
class Timer{
 ...
 static unsigned __stdcall tick(void *param){
    while(1){
        Timer::timer++;
        Sleep(Timer::timer*1000);
    }
    return 1;
}
}

.....
HANDLE time_thread = (HANDLE) _beginthreadex(0, 0, &Timer::tick,0,0,NULL);
...
//test for 20 seconds
//want to do something while the clock is not 20 seconds
//the mainthread here still has to receive input
//What is the proper way to do it?

while (Timer::getTime() != 20){
   cout << Timer::getTime()
}

CloseHandle(time_thread);
...

注意:我使用的是Visual Studio 2008,而不是11,因此我没有C++11支持。

2个回答

1
我不确定这里有什么问题。您创建了一个更新成员变量timer的线程,而其主要用途是打印(可能是)达到20的时间的紧密/快速循环。它做不到什么?在技术上,在另一个线程中增加该值与检查该值存在竞态条件,但对于本示例,应该没有问题...编辑:尝试使用此方法进行非阻塞输入并具有完全输入控制:
HANDLE hStdIn = GetStdHandle( STD_INPUT_HANDLE );
while ( true ) {
    if ( WAIT_OBJECT_0 == WaitForSingleObject( hStdIn, 1000 ) ) {
        // read input
        INPUT_RECORD inputRecord;
        DWORD events;
        if ( ReadConsoleInput( hStdIn, &inputRecord, 1, &events ) ) {
            if ( inputRecord.EventType == KEY_EVENT ) {
                printf( "got char %c %s\n",
                    inputRecord.Event.KeyEvent.uChar.AsciiChar,
                    inputRecord.Event.KeyEvent.bKeyDown ? "down" : "up" );
            }
        }
    }
    printf( "update clock\n" );
}

它将打印出类似于“00000001111111111112222222222222222333333333333333333......”的内容。如何使其在递增时,主线程仍然可以接收输入?比如说,如果它不是20,你仍然可以输入单词。 - DucHo DucHo
我们是在讨论控制台程序还是Windows GUI程序? - mark
如果您只是想检查控制台输入是否达到了20秒,那么如果没有任何输入,您应该查看GetStdHandle(STD_INPUT_HANDLE)WaitForSingleObject,然后跳过线程。根据您要执行的操作,您可能还需要使用SetConsoleMode - mark
这不是GUI程序,而是控制台程序。我只想制作一个简单的时钟,它会滴答作响,并且在某些时间点上我可以做其他事情(例如调用一些函数,如end),但在滴答声中,我可以在控制台上输入。 - DucHo DucHo
你可以在循环中使用 WaitForSingleObject 函数等待标准输入句柄 1000 毫秒(1 秒)。每次从等待中返回时更新时钟并检查输入。 - mark
显示剩余2条评论

0

很抱歉,你对系统计时器的工作原理和使用方法有所误解 - 整个重点在于它们会自动在后台运行,因此你不需要自己进行线程管理。

这里有一些关于Windows计时器的示例和解释,如果你想要自己编写一个Timer类,可以参考:计时器教程

这是Windows.NET自带的Timer类,底部有一个代码示例:Timer类

编辑补充:

这是一个非MFC应用程序适用的Win32计时器示例(来自教程页面)的版本:

int nTimerID;

void Begin(HWND hWindow_who_gets_the_tick)
{
    // create the timer to alert your window:
    nTimerID = SetTimer(hWindow_who_gets_the_tick, uElapse, NULL);
}

void Stop()
{
    // destroy the timer
    KillTimer(nTimerID);
}

请参阅MSDN:计时器函数以获取详细信息。

然后在您的窗口过程中,您会收到WM_TIMER消息,并根据需要进行响应。

或者,计时器可以调用用户定义的过程。请参阅SetTimer函数以获取详细信息。


我会看一下。谢谢。有没有不需要 MFC 的解决方案? - DucHo DucHo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接