需要帮助实现C ++中的计时器/自动收录器类

时间:2014-07-16 10:50:50

标签: c++ multithreading timer cross-platform ticker

需要帮助实现具有启动/停止/暂停功能的ticker类,可分配的回调(onTick),并在每个间隔跨度的单独线程上执行。间隔跨度是可指定和可更新的。希望它应该是跨平台的。

这是我天真的尝试,但它并不好(start()中的while循环当前是阻塞的,但理想情况下它应该在一个单独的线程上运行,但我无法弄清楚如何实现它)因为我是C ++多线程模型中的漂亮菜鸟:

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

我的尝试完全错了,或者它非常接近?

1 个答案:

答案 0 :(得分:1)

请考虑以下代码以及使用示例。我希望我能正确理解你。 只需在一个单独的线程中运行while循环。

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