在Linux上,我将使用fork()创建一个子进程,它将是我的倒计时器,一旦计时器结束,子进程将向父进程发送一个信号告诉它计时器已经结束。然后父进程应该相应地处理信号。
我不知道如何在Windows上执行此操作。这里的一些人建议使用线程,但他们从未编写任何示例代码来说明如何执行此操作。
最重要的是计时器是非阻塞的,这意味着它在后台继续倒计时,而程序正在接受用户的输入并正常处理。
你能告诉我怎么样吗?
修改
该应用程序是一个控制台。请告诉我示例代码。谢谢!
更新
所以在我阅读了一些建议之后,我在这里搜索了一些答案并找到了这个one,这很有帮助。
然后我编写了下面的代码,它起作用,但并不像它应该的那样:
#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()甚至会读取之前输入的文本!我该怎么办呢?如果有更好的方法,请你指点一下吗?
答案 0 :(得分: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;
}
主要功能基本上创建一个使用过程threadProc
执行的线程。您可以将threadProc
视为主题。一旦结束,线程结束。
threadProc
每秒输出一次运行计数,而main函数则等待阻塞输入。一旦给出输入,整个事情就会结束。
另请注意CreateThread
使用最少的参数。它返回一个可以在WaitForSingleObject
之类的函数中使用的线程的句柄,最后一个参数可以接收线程id。
答案 1 :(得分:4)
您可以在线程内外使用Waitable Timer Objects。要使用此类对象,只需使用SetWaitableTimer
函数。根据MSDN的功能定义:
激活指定的等待计时器。当到期时间到来时,定时器被发出信号,并且设置定时器的线程调用可选的完成例程。
答案 2 :(得分:1)
如果你为它们实现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秒钟来设置expiration标志,然后再次等待线程,直到它完成其功能。
答案 3 :(得分:0)
寻找同一问题的解决方案,我发现这篇文章非常有用:
http://www.codeproject.com/Articles/1236/Timers-Tutorial
正如您似乎已经想到的那样,最好的答案(在Windows 2000之后的世界中)似乎是队列计时器,而不是CreateTimerQueueTimer。
答案 4 :(得分:-2)
试试这个:
//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++;
}
}