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:
- after calling
start
thefunc
object is called without any delay. reset
method does not work