如何安装重复发生的计时器功能



是否有一种简单的方法可以使用C /stdlib安装定期出现的计时器函数?我想摆脱循环:

using namespace std::chrono; // literal suffixes
auto tNext = steady_clock::now();
while (<condition>) {
    std::this_thread::sleep_until(tNext);
    tNext = tNext + 100ms; 
    ...

该功能将以自己的线程运行。

我猜你想要什么

int i = 10;
auto pred = [i]() mutable {return i--;};
auto print = []{cout << "." << endl;};
timer t{500ms};
t.push({print, pred});  //asynchronously prints '.' 10 times within 5s
//do anything else

假设性能并不关键,并且计时器不经常更新,以下内容应提供足够的功能。

#include<functional>
#include<vector>
#include<thread>
#include<utility>
#include<chrono>
#include<mutex>
#include<atomic>
class timer final
{
public:
    using microseconds = std::chrono::microseconds;
    using predicate = std::function<bool ()>;
    using callback = std::function<void ()>;
    using job = std::pair<callback, predicate>;
    explicit timer(microseconds t) : done{false}, period{t}
    {
        std::lock_guard<std::mutex> lck(mtx);
        worker = std::thread([this]{
            auto t = std::chrono::steady_clock::now();
            while(!done.load())
            {
                std::this_thread::sleep_until(t);
                std::lock_guard<std::mutex> lck(mtx);
                t += period;
                for(auto it = jobs.begin(); it != jobs.end();)
                {
                    if(it->second())
                        it++->first();
                    else
                        it = jobs.erase(it);
                }
            }
        });
    }
    ~timer()
    {
        done.store(true);
        worker.join();
    }
    void set_period(microseconds t)
    {
        std::lock_guard<std::mutex> lck(mtx);
        period = t;
    }
    void push(const callback& c)
    {
        std::lock_guard<std::mutex> lck(mtx);
        jobs.emplace_back(c, []{return true;});
    }
    void push(const job& j)
    {
        std::lock_guard<std::mutex> lck(mtx);
        jobs.push_back(j);
    }
private:
    std::mutex mtx;
    std::atomic_bool done;
    std::thread worker;
    std::vector<job> jobs;
    microseconds period;
};

timer先前定期按callback s的调用,当predicate评估false时,将callbacktimer删除。timer对象具有自己的寿命,只要活着,它的工作线程就会活。

您希望在单个timer中拥有多个job s的原因是这样可以将它们调用,仅使用一个线程并彼此同步。

,除非您打算每秒更新计时器> 10,000次,否则请不要担心mutex,有一个lt; 1ms的时期或耗时的callback s。

最新更新