在Windows中创build一个C ++非阻塞计时器

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

我不知道如何在Windows上做到这一点。 这里的一些人推荐使用线程,但是他们从来没有写过任何示例代码来显示如何去做。

最重要的是定时器是非阻塞的,意味着它在后台保持倒计时,而程序正在接受用户的input并正常处理。

你能告诉我怎么样?

编辑:

该应用程序是一个控制台之一。 请给我示例代码。 谢谢!

更新:

所以在阅读了这里的一些build议之后,我在这里search了一些答案,发现这个有帮助。

然后,我写了下面的代码,它的工作,但不是它应该是:

#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; } 

问题是,中断的getline()永远不会停止,随后的getline()甚至会读取之前input的文本! 我该如何解决这个问题? 如果还有更好的方法,请指点一下吗?

Solutions Collecting From Web of "在Windows中创build一个C ++非阻塞计时器"

以下是一个适用于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; } 

基本上,主函数创建一个使用过程threadProc执行的线程。 您可以将threadProc视为线程。 一旦结束,线程结束。

threadProc只是threadProc输出一个运行计数,而主函数等待一个阻塞输入。 一旦给出了输入,整个事情就结束了。

另外请注意, CreateThread使用最少的参数。 它返回一个线程的句柄,你可以在WaitForSingleObject这样的函数中使用它,最后一个参数可以接收线程的ID。

您可以在线程内部或外部使用Waitable Timer Objects 。 要使用这种类型的对象,只需使用SetWaitableTimer函数。 根据MSDN的函数定义:

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

这是另一个解决方案,它将跨平台,如果您为他们实现kbhit()函数:

 #include <boost/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/date_time/posix_time/posix_time.hpp> #if defined(WIN32) #include <conio.h> #else // kbhit() implementation for other platforms #endif boost::mutex mutex_; bool timeExpired_ = false; void threadFunc() { while(1) { { boost::mutex::scoped_lock lock(mutex_); if (timeExpired_) break; #if defined(WIN32) kbhit(); #endif } boost::this_thread::sleep(boost::posix_time::milliseconds(1)); } } int main(int argc, char *argv[]) { boost::thread worker(threadFunc); worker.timed_join(boost::posix_time::milliseconds(5000)); { boost::mutex::scoped_lock lock(mutex_); timeExpired_ = true; } worker.join(); return 0; } 

这种方法使用boost :: thread,并在创建线程之后等待5秒钟来设置过期标志,然后再等待该线程,直到完成其功能。

寻找同样的问题的解决方案,我发现这篇文章非常有帮助:

http://www.codeproject.com/Articles/1236/Timers-Tutorial

正如你似乎已经发现,最好的答案(在后Windows 2000的世界)似乎是Queue Timers, CreateTimerQueueTimer 。

试试这个:

 //Creating Digital Watch in C++ #include<iostream> #include<Windows.h> using namespace std; struct time{ int hr,min,sec; }; int main() { time a; a.hr = 0; a.min = 0; a.sec = 0; for(int i = 0; i<24; i++) { if(a.hr == 23) { a.hr = 0; } for(int j = 0; j<60; j++) { if(a.min == 59) { a.min = 0; } for(int k = 0; k<60; k++) { if(a.sec == 59) { a.sec = 0; } cout<<a.hr<<" : "<<a.min<<" : "<<a.sec<<endl; a.sec++; Sleep(1000); system("Cls"); } a.min++; } a.hr++; } }