Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在5分钟后,当其他代码仍在C++;_C++_Multithreading_Class_Timer - Fatal编程技术网

C++ 在5分钟后,当其他代码仍在C++;

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

我正在试着做一个计时器,所以五分钟后会发生一些事情。问题是,当计时器不断被检查时,我需要运行其他代码。我在下面创建了一个示例,演示了代码的实际外观,带计时器的函数在类中,所以我在下面做了同样的事情。代码如下:

此代码假定包含所有必要的标题

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.";
}
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;
}