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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21521282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:41:10  来源:igfitidea点击:

Basic timer with std::thread and std::chrono

c++multithreadingc++11timer

提问by Sysyfydev

I'm trying to implement a basic timer with the classic methods: start() and stop(). I'm using c++11 with std::thread and std::chrono.

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

  • Start method. Creates a new thread that is asleep for a given interval time, then execute a given std::function. This process is repeated while a 'running' flag is true.
  • Stop method. Just sets the 'running' flag to false.
  • 启动方法。创建一个在给定间隔时间内休眠的新线程,然后执行给定的 std::function。当“运行”标志为真时,重复此过程。
  • 停止方法。只需将 'running' 标志设置为 false。

I created and started a Timer object that show "Hello!" every second, then with other thread I try to stop the timer but I can't. The Timer never stops.

我创建并启动了一个显示“你好!”的 Timer 对象。每一秒,然后与其他线程我试图停止计时器,但我不能。计时器永远不会停止。

I think the problem is with th.join()[*] that stops execution until the thread has finished, but when I remove th.join() line obviously the program finishes before the timer start to count.

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

So, my question is how to run a thread without stop other threads?

所以,我的问题是如何在不停止其他线程的情况下运行一个线程?

#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;
}

Output:

输出:

Hello!
Hello!
...
...
...
Hello!

回答by Casey

In Timer::start, you create a new thread in thand then immediately joinit with th.join(). Effectively, startwon't return until that spawned thread exits. Of course, it won't ever exit because nothing will set running to false until after startreturns...

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

Don't joina thread until you intend to wait for it to finish. In this case, in stopafter setting running = falseis probably the correct place.

join您打算等待它完成之前不要线程。在这种情况下,in stopafter settingrunning = false可能是正确的地方。

Also - although it's not incorrect - there's no need to make another thread in mainto call this_thread::sleep_for. You can simply do so with the main thread:

此外 - 虽然它不是不正确 - 没有必要创建另一个线程main来调用this_thread::sleep_for. 您可以简单地使用主线程执行此操作:

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

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

回答by hsun324

Instead of placing the joinin startplace it after running = falsein stop. Then the stop method will effectively wait until the thread is completed before returning.

而不是放置joinstart后的地方它running = falsestop。然后 stop 方法会有效地等待线程完成后再返回。