Need help in implementation of a timer/ticker class in C++

别来无恙 提交于 2019-12-11 12:48:12

问题


Need help in implementing a ticker class with start/stop/pause functionality, assignable callback (onTick) with execution on a separate thread every interval span. Interval span is specifiable and update-able. Hopefully it should be cross-platform.

Here is my naive attempt, but it's not good (the while loop in start() is blocking currently, but ideally it should run on a separate thread but I can't figure out how to achieve it) as I'm pretty noob in C++ multithreading model:

#include <cstdint>
#include <functional>
#include <chrono>
#include <thread>
#include <future>

class Ticker {
public:
    typedef std::chrono::duration<int64_t, std::nano> tick_interval_t;
    typedef std::function<void()> on_tick_t;

    Ticker (std::function<void()> onTick, std::chrono::duration<int64_t, std::nano> tickInterval) 
    : _onTick (onTick)
    , _tickInterval (tickInterval)
    , _running (false) {}
    ~Ticker () {}

    void start () {
        if (_running) return;
        _running = true;
        while (_running) {
            std::async( std::launch::async, _onTick );
            std::this_thread::sleep_for( _tickInterval );
        }
    }
    void stop () { _running = false; }

private:
    on_tick_t           _onTick;
    tick_interval_t     _tickInterval;
    bool                _running;
};

I'm a completely wrong in my attempt or it's pretty close?


回答1:


Consider the following code with example of usage. I hope I understood you correctly. Just run your while loop in a separate thread.

#include <cstdint>
#include <functional>
#include <chrono>
#include <thread>
#include <future>
#include <condition_variable>
#include <iostream>
#include <mutex>

class Ticker {
public:
    typedef std::chrono::duration<int64_t, std::nano> tick_interval_t;
    typedef std::function<void()> on_tick_t;

    Ticker (std::function<void()> onTick, std::chrono::duration<int64_t, std::nano> tickInterval) 
    : _onTick (onTick)
    , _tickInterval (tickInterval)
    , _running (false) {}
    ~Ticker () {}

    void start () {
        if (_running) return;
        _running = true;
        std::thread run(&Ticker::timer_loop, this);
        run.detach();
    }

    void stop () { _running = false; }

    void setDuration(std::chrono::duration<int64_t, std::nano> tickInterval)
    {
        _tickIntervalMutex.lock();
        _tickInterval = tickInterval;
        _tickIntervalMutex.unlock();
    }

private:
    void timer_loop()
    {
        while (_running) {
            std::thread run(_onTick );
            run.detach();

            _tickIntervalMutex.lock();
            std::chrono::duration<int64_t, std::nano> tickInterval = _tickInterval;
            _tickIntervalMutex.unlock();
            std::this_thread::sleep_for( tickInterval );
        }
    }

    on_tick_t           _onTick;
    tick_interval_t     _tickInterval;
    volatile bool       _running;
    std::mutex          _tickIntervalMutex;
};

void tick()
{
    std::cout << "tick\n";
}

void main()
{
    std::chrono::duration<int, std::milli> timer_duration1(1000);
    std::chrono::duration<int, std::milli> timer_duration2(500);
    std::chrono::duration<int> main_wait(5);

    Ticker ticker(std::function<void()>(tick), timer_duration1);
    ticker.start();

    std::this_thread::sleep_for(main_wait);
    ticker.setDuration(timer_duration2);
    std::this_thread::sleep_for(main_wait);
    ticker.stop();
}


来源:https://stackoverflow.com/questions/24778929/need-help-in-implementation-of-a-timer-ticker-class-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!