C++ 在5分钟后,当其他代码仍在C++;
我正在试着做一个计时器,所以五分钟后会发生一些事情。问题是,当计时器不断被检查时,我需要运行其他代码。我在下面创建了一个示例,演示了代码的实际外观,带计时器的函数在类中,所以我在下面做了同样的事情。代码如下: 此代码假定包含所有必要的标题 h类:C++ 在5分钟后,当其他代码仍在C++;,c++,multithreading,class,timer,C++,Multithreading,Class,Timer,我正在试着做一个计时器,所以五分钟后会发生一些事情。问题是,当计时器不断被检查时,我需要运行其他代码。我在下面创建了一个示例,演示了代码的实际外观,带计时器的函数在类中,所以我在下面做了同样的事情。代码如下: 此代码假定包含所有必要的标题 h类: class MyClass { public: void TimerFunc(int MSeconds); }; void MyClass::TimerFunc(int MSeconds) { Sleep(MSeconds); //W
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.";
}
intmain()
{
MyClass MyClass;
myClass.TimerFunc(300);//300是5分钟
//在这里,我们不想等待五分钟过去,
//相反,我们希望继续代码的其余部分并检查
//供用户输入,如下所示
如果您不介意在不同的线程上下文中执行事件,您可以让计时器类生成一个线程来执行等待,然后再执行事件;或者(在POSIX操作系统上)设置一个SIGALRM信号并让信号处理程序处理该事件。这样做的缺点是,如果您的事件代码做了任何非平凡的事情,您将需要担心并发执行的主线程的争用条件
另一种方法是让主线程每隔一段时间检查一次时钟,如果执行时间已过,则让主线程在该时间调用事件例程。这具有自动线程安全的优点,但缺点是必须将该代码添加到线程的主事件循环中;您无法轻松隐藏它被放在一个类中,就像你例子中的那样。对于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
在类a成员函数中预见停止线程循环:
void Stop() {
run = false;
}
最后更新main()
以在不再需要计时器函数时调用myClass.Stop()
(即在调用ti.join()
之前)
编辑:注意,要避免的严重错误:小心参考ref(myClass)
在线程构造函数中。如果您忘记了这一点,线程ti
将使用对myClass副本的引用,而不是原始对象。您应该使用某种形式的睡眠,而不是原始对象。是的,线程将是一个选项,但它取决于事件处理如何与其余代码交互。是的,执行“事件代码”和“其他代码”必须相互通信、合作或交互?好的,当然是Sleep()是一个更好的选择…老实说,我不知道为什么我第一次想到上述内容,事件代码只设置了一个变量。代码的其余部分将在稍后使用该变量,但不会在设置后立即使用。然后听起来好像需要线程(并且假设代码的其余部分在变量准备好之前不会寻找它,这是危险的。)while(time(0)
的循环可能更容易阅读。while(true)if(condition)break;的结构非常奇怪,通常这会读得更好(更短!)如果写为while(!condition);
。第三种可能是异步事件。我似乎回忆起boostI中的一些支持。我认为线程是我将如何进行的,正如我在主要帖子中的评论所述,它只需要设置一个变量。
void Stop() {
run = false;
}