0

I want a Timer class with reset method. When the reset method is called, std::function<void(void)> func execution will be postponed for next interval milliseconds. Here is my code (obtained from C++ 11: Calling a C++ function periodically) (the reset method doesn't work correctly):

// .h
class Timer
{
public:
    Timer(const int interval, const std::function<void(void)>& func);
    ~Timer();
    void stop();
    void start();
    bool is_running() const noexcept;
    void reset();

private:
    const int interval_;
    const std::function<void(void)> func_;
    std::atomic<bool> execute_;
    std::thread thd_;
};

//////////////////////////////////////////////////////////////////////////////////
// .cpp

utl::Timer::Timer(const int interval, const std::function<void(void)>& func) :
    func_{ func },
    interval_{ interval },
    execute_(false)
{
}

utl::Timer::~Timer()
{
    if (execute_.load(std::memory_order_acquire)) {
        stop();
    };
}

void utl::Timer::stop()
{
    execute_.store(false, std::memory_order_release);
    if (thd_.joinable())
        thd_.join();
}

void utl::Timer::start()
{
    if (execute_.load(std::memory_order_acquire)) {
        stop();
    };
    execute_.store(true, std::memory_order_release);
    thd_ = std::thread([this]()
        {
            while (execute_.load(std::memory_order_acquire)) {
                func_();
                std::this_thread::sleep_for(
                    std::chrono::milliseconds(interval_));
            }
        });
}

bool utl::Timer::is_running() const noexcept {
    return (execute_.load(std::memory_order_acquire) &&
        thd_.joinable());
}

void utl::Timer::reset()
{
    stop();
    start();
}

//////////////////////////////////////////////////////////////////////////////////
// a main function for test
#include <iostream>

using namespace std;
using namespace utl;

int main()
{
    Timer timer(5000, []() {
        cout << "reached!" << endl;
        });

    timer.start();
    while (true)
    {
        cout << "working ...";
        this_thread::sleep_for(std::chrono::seconds(1));
        timer.reset();
    }
}

This output of the main function (it is expected that string "reached!" not showed in cmd):

working ...
reached!
working ...
reached!
working ...
reached!
.
.
.

My problems are:

  1. after calling start the func object is called without any delay.
  2. reset method does not work
Babak.Abad
  • 2,839
  • 10
  • 40
  • 74

0 Answers0