我正在尝试制作一个计时器,所以五分钟后会发生一些事情。问题是,在定期检查计时器时,我需要运行其他代码。我在下面创建了一个示例,实际代码看起来如何,带有计时器的函数在类中,所以我在下面做了同样的事情。这是代码:
此代码假定包含所有必需的标题
Class.h:
class MyClass
{
public:
void TimerFunc(int MSeconds);
};
void MyClass::TimerFunc(int MSeconds)
{
Sleep(MSeconds); //Windows.h
//Event code
return;
}
Main.cpp的:
int main()
{
MyClass myClass;
myClass.TimerFunc(300); //300 is 5 minutes
//Here we do not want to wait for the five minutes to pass,
//instead we want to continue the rest of the code and check
//for user input as below
std::cout << "This should print before the Event Code happens.";
}
这里的问题是代码等待五分钟通过,然后继续。我不确定线程在这里是不是一个好选择,我之前没有做过多少,如果有人可以帮助我,或者知道更好的方法去做,任何帮助都会受到赞赏。
答案 0 :(得分:0)
如果您不介意在不同的线程上下文中执行事件,您可以让Timer类生成一个线程来执行等待,然后执行事件;或者(在POSIX操作系统上)设置SIGALRM信号并让信号处理程序执行事件。这样做的缺点是,如果你的事件代码做了一些非常重要的事情,那么你需要担心同时执行主线程的竞争条件。
另一种方法是让你的主线程经常检查时钟,如果执行时间已经过去,那么让主线程在那时调用你的事件例程。这具有自动线程安全的优点,但缺点是您必须将该代码添加到线程的主事件循环中;你不能轻易地将它隐藏在像你的例子那样的类中。
答案 1 :(得分:0)
使用C ++ 11线程,这可以这样工作:
int main()
{
MyClass myClass;
thread ti([](MyClass &m){m.TimerFunc(300); }, ref(myClass)); // create and launch thread
// ... code executed concurrently to threaded code
ti.join(); // wait for the thread to end (or you'll crash !!)
}
在您的班级中添加私人会员:
atomic<bool> run=true; // designed to avoid race issue with concurrent access
当此变量为true时,将其计时器功能更新为循环:
void MyClass::TimerFunc(int MSeconds)
{
while (run) {
this_thread::sleep_for(chrono::milliseconds(MSeconds)); // standard sleep instead of microsoft's one
//Event code
}
return;
}
在类中预见一个成员函数来停止线程循环:
void Stop() {
run = false;
}
最后更新main()
以便在不再需要定时器功能时调用myClass.Stop()
(即在调用ti.join()
之前)
编辑: 注意,要避免令人讨厌的错误:请小心在线程构造函数中引用ref(myClass)
。如果你忘了这一点,线程ti
将使用对myClass副本的引用而不是原始对象。