C++ 带std::thread和std::chrono的基本计时器

C++ 带std::thread和std::chrono的基本计时器,c++,multithreading,c++11,timer,C++,Multithreading,C++11,Timer,我试图用经典的方法实现一个基本的计时器:start()和stop()。我将c++11与std::thread和std::chrono一起使用 启动方法。创建一个在给定间隔时间内处于休眠状态的新线程,然后执行给定的std::函数。当“正在运行”标志为真时,重复此过程 停止方法。只需将“running”标志设置为false 我创建并启动了一个计时器对象,该对象每秒显示“Hello!”,然后使用其他线程尝试停止计时器,但我无法停止。计时器从不停止 我认为问题在于th.join()[*]在线程完成之

我试图用经典的方法实现一个基本的计时器:start()和stop()。我将c++11与std::thread和std::chrono一起使用

  • 启动方法。创建一个在给定间隔时间内处于休眠状态的新线程,然后执行给定的std::函数。当“正在运行”标志为真时,重复此过程
  • 停止方法。只需将“running”标志设置为false
我创建并启动了一个计时器对象,该对象每秒显示“Hello!”,然后使用其他线程尝试停止计时器,但我无法停止。计时器从不停止

我认为问题在于th.join()[*]在线程完成之前停止执行,但是当我删除th.join()行时,程序显然会在计时器开始计数之前完成

所以,我的问题是如何运行一个线程而不停止其他线程

#include <iostream>
#include <thread>
#include <chrono>

using namespace std;

class Timer
{
    thread th;
    bool running = false;

public:
    typedef std::chrono::milliseconds Interval;
    typedef std::function<void(void)> Timeout;

    void start(const Interval &interval,
               const Timeout &timeout)
    {
        running = true;

        th = thread([=]()
        {
            while (running == true) {
                this_thread::sleep_for(interval);
                timeout();
            }
        });

// [*]
        th.join();
    }

    void stop()
    {
        running = false;
    }
};

int main(void)
{
    Timer tHello;
    tHello.start(chrono::milliseconds(1000),
                 []()
    {
        cout << "Hello!" << endl;
    });

    thread th([&]()
    {
        this_thread::sleep_for(chrono::seconds(2));
        tHello.stop();
    });

    th.join();

    return 0;
}

Timer::start
中,您可以在
th
中创建一个新线程,然后立即
join
使用
th.join()。实际上,
start
在生成的线程退出之前不会返回。当然,它永远不会退出,因为在
start
返回之前,不会将running设置为false

在您打算等待线程完成之前,不要加入线程。在这种情况下,在设置
running=false
后的
stop
中可能是正确的位置

另外-虽然这并不错误-没有必要在
main
中创建另一个线程来调用
此线程::sleep\u for
。只需使用主线程即可:

int main()
{
    Timer tHello;
    tHello.start(chrono::milliseconds(1000), []{
        cout << "Hello!" << endl;
    });

    this_thread::sleep_for(chrono::seconds(2));
    tHello.stop();
}
intmain()
{
定时器tHello;
tHello.start(时钟::毫秒(1000),[]{

cout而不是将
join
放在
start
中,将它放在
running=false
之后,放在
stop
中。这样,stop方法将有效地等待线程完成后再返回。

作为一个旁注,根据我的经验,使用condition\u变量也更有效(因为它是为这种事情而设计的)。但是它使代码不那么清晰。
int main()
{
    Timer tHello;
    tHello.start(chrono::milliseconds(1000), []{
        cout << "Hello!" << endl;
    });

    this_thread::sleep_for(chrono::seconds(2));
    tHello.stop();
}