簡體   English   中英

帶有std :: thread和std :: chrono的基本計時器

[英]Basic timer with std::thread and std::chrono

我正在嘗試使用經典方法實現基本計時器:start()和stop()。 我正在使用帶有std :: thread和std :: chrono的c ++ 11。

  • 啟動方法。 創建一個在給定間隔時間內處於睡眠狀態的新線程,然后執行給定的std :: function。 當'running'標志為真時,重復此過程。
  • 停止方法。 只需將'running'標志設置為false即可。

我創建並啟動了一個顯示“Hello!”的Timer對象。 每一秒,然后與其他線程我試圖停止計時器,但我不能。 計時器永不停止。

我認為問題在於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;
}

輸出:

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

Timer::start ,您在th創建一個新線程,然后立即join其與th.join() 實際上,在生成的線程退出之前, start不會返回。 當然,它永遠不會退出,因為在start返回之后,沒有任何東西會設置為false。

在您打算等待它完成之前,請不要join線程。 在這種情況下,在設置running = falsestop可能是正確的位置。

另外 - 雖然它不是不正確的 - 沒有必要在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();
}

而不是將join置於start位置,而是在stop running = false之后。 然后stop方法將有效地等到線程完成后再返回。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM