在Windows中创建C++非阻塞计时器

Ahm*_*hry 1 c++ windows winapi visual-c++

在Linux上,我将使用fork()创建一个子进程,它将是我的倒计时器,一旦计时器结束,子进程将向父进程发送一个信号,告诉它计时器已经结束.然后父进程应该相应地处理信号.

我不知道如何在Windows上执行此操作.这里的一些人建议使用线程,但他们从未编写任何示例代码来说明如何执行此操作.

最重要的是计时器是非阻塞的,这意味着它在后台仍然倒计时,而程序正在接受用户的输入并正常处理它.

你能告诉我怎么样吗?

编辑:

该应用程序是一个控制台.请告诉我示例代码.谢谢!

更新:

所以在我阅读了这里的一些建议之后,我在这里搜索了一些答案并找到了一个有用的答案.

然后我编写了下面的代码,它可以工作,但并不像它应该的那样:

#include <Windows.h>
#include <iostream>
#include <string>
using namespace std;

#define TIMER_VALUE (5 * 1000) //5 seconds = 5000 milli seconds
HANDLE g_hExitEvent = NULL;

bool doneInTime = false;
string name;

bool inputWords();


//The below function will be called when the timer ends
void CALLBACK doWhenTimerEnds(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
    if(!doneInTime)
    {
        cout << "\nOut of time ... try again ..." << endl;
        name = "";
        doneInTime = inputWords();
    }
    SetEvent(g_hExitEvent);
}


bool inputWords()
{

    /* doWhenTimerEnds() will be called after time set by 5-th parameter and repeat every 6-th parameter. After time elapses,
    callback is called, executes some processing and sets event to allow exit */
    HANDLE hNewTimer = NULL; 
    BOOL IsCreated = CreateTimerQueueTimer(&hNewTimer, NULL, doWhenTimerEnds, NULL, TIMER_VALUE, 0, WT_EXECUTELONGFUNCTION);

    g_hExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    cout << "Input your name in 5 seconds .. " << endl;
    std::getline(cin, name);

    DeleteTimerQueueTimer(NULL, hNewTimer, NULL);
    return true;
}

int main()
{
    doneInTime = inputWords();
    cout << "Hello, " << name << "! You're done in time" << endl;

    //WaitForSingleObject(g_hExitEvent, 15000);

    system("pause");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

问题是,中断的getline()永远不会停止,后续的getline()甚至会读取先前输入的文本!我该怎么办呢?如果有更好的方法,请你指点一下吗?

chr*_*ris 5

以下是适用于Windows API的示例:

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

DWORD WINAPI threadProc()
{
    for (int i = 0; ; ++i)
    {
        std::cout << i << '\n';
        Sleep (1000);
    }

    return 0;
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                    LPSTR lpszCmdLine, int iCmdShow)
{
    CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)threadProc, NULL, 0, NULL);

    int i;
    std::cin >> i;

    return ERROR_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

基本上main函数创建一个使用该过程执行的线程threadProc.你可以把它想象threadProc成线程.一旦结束,线程结束.

threadProc只需每秒输出一次运行计数,而main函数则等待阻塞输入.一旦给出输入,整个事情就结束了.

另请注意,CreateThread使用最少的参数.它返回一个可以在函数中使用的线程的句柄,WaitForSingleObject最后一个参数可以接收线程id.


gah*_*cep 5

您可以在线程内部或外部使用可等待计时器对象。要使用此类对象只需使用SetWaitableTimer函数即可。根据MSDN的函数定义:

激活指定的可等待计时器。当到期时间到达时,计时器会收到信号,并且设置计时器的线程会调用可选的完成例程。