Timer calling a function at regular interval interval - c++

static void timer_start(std::function<void(void)> func, unsigned int interval)
{
std::thread([func, interval]()
{
while (true)
{
auto x = std::chrono::steady_clock::now() + std::chrono::milliseconds(interval);
func();
std::this_thread::sleep_until(x);
}
}).detach();
}
static void interfacetoBackend()
{
}
int main(){
timer_start(interfacetoBackend, 2000);
}
I have a timer calling a function at regular interval as shown above.
I like to stop before the program end.
Currently, I can't stop the timer.
How can I stop the timer call?

Related

How could one delay a function without the use of sleep / suspending the code?

I need to delay a function by x amount of time. The problem is that I can't use sleep nor any function that suspends the function (that's because the function is a loop that contains more function, sleeping / suspending one will sleep / suspend all)
Is there a way I could do it?
If you want to execute some specific code at a certain time interval and don't want to use threads (to be able to suspend), then you have to keep track of time and execute the specific code when the delay time was exceeded.
Example (pseudo):
timestamp = getTime();
while (true) {
if (getTime() - timestamp > delay) {
//main functionality
//reset timer
timestamp = getTime();
}
//the other functionality you mentioned
}
With this approach, you invoke a specific fuction every time interval specified by delay. The other functions will be invoked at each iteration of the loop.
In other words, it makes no difference if you delay a function or execute it at specific time intervals.
Assuming that you need to run functions with their own arguments inside of a loop with custom delay and wait for them to finish before each iteration:
#include <cstdio>
void func_to_be_delayed(const int &idx = -1, const unsigned &ms = 0)
{
printf("Delayed response[%d] by %d ms!\n", idx, ms);
}
#include <chrono>
#include <future>
template<typename T, typename ... Ta>
void delay(const unsigned &ms_delay, T &func, Ta ... args)
{
std::chrono::time_point<std::chrono::high_resolution_clock> start = std::chrono::high_resolution_clock::now();
double elapsed;
do {
std::chrono::time_point<std::chrono::high_resolution_clock> end = std::chrono::high_resolution_clock::now();
elapsed = std::chrono::duration<double, std::milli>(end - start).count();
} while(elapsed <= ms_delay);
func(args...);
}
int main()
{
func_to_be_delayed();
const short iterations = 5;
for (int i = iterations; i >= 0; --i)
{
auto i0 = std::async(std::launch::async, [i]{ delay((i+1)*1000, func_to_be_delayed, i, (i+1)*1000); } );
// Will arrive with difference from previous
auto i1 = std::async(std::launch::async, [i]{ delay(i*1000, func_to_be_delayed, i, i*1000); } );
func_to_be_delayed();
// Loop will wait for all calls
}
}
Notice: this method potentially will spawn additional thread on each call with std::launch::async type of policy.
Standard solution is to implement event loop.
If you use some library, framework, system API, then most probably there is something similar provided to solve this kind of problem.
For example Qt has QApplication which provides this loop and there is QTimer.
boost::asio has io_context which provides even loop in which timer can be run boost::asio::deadline_timer.
You can also try implement such event loop yourself.
Example wiht boost:
#include <boost/asio.hpp>
#include <boost/date_time.hpp>
#include <exception>
#include <iostream>
void printTime(const std::string& label)
{
auto timeLocal = boost::posix_time::second_clock::local_time();
boost::posix_time::time_duration durObj = timeLocal.time_of_day();
std::cout << label << " time = " << durObj << '\n';
}
int main() {
boost::asio::io_context io_context;
try {
boost::asio::deadline_timer timer{io_context};
timer.expires_from_now(boost::posix_time::seconds(5));
timer.async_wait([](const boost::system::error_code& error){
if (!error) {
printTime("boom");
} else {
std::cerr << "Error: " << error << '\n';
}
});
printTime("start");
io_context.run();
} catch (const std::exception& e) {
std::cerr << e.what() << '\n';
}
return 0;
}
https://godbolt.org/z/nEbTvMhca
C++20 introduces coroutines, this could be a good solution too.

How to delete boost io_service

My simplified question
I read this thread and I am trying to delete the io_service object. I do this
m_IO.stop();
m_IO.~io_service();
m_IO is an object of boost::asio::io_service. I found that my thread was blocked by m_IO.~io_service(); How can I delete io_service?
My Complete question
I am making a daily timer by using boost io_service and deadline timer. The problem is when I want to delete my daily timer, my thread will disappear when it try to delete boost io_service.
main.cpp
int main()
{
myDailyTimer* pTimer = new myDailyTimer;
// do something
delete pTimer;
return 0;
}
I set break points in myDailyTimer.cpp::int i = 0; and myDailyTimer.cpp::int j = 0; and main::return 0; My main thread can reach int i = 0;, My timer thread cannot reach int j = 0;, My main thread cannot reach return 0;.
I found the my main thread will disappear when it try to delete boost::asio::io_service object. How to solve this problem? Am I using boost::asio::io_service in a wrong way?
myDailyTimer.h
class myDailyTimerInterface
{
public:
myDailyTimerInterface(){}
~myDailyTimerInterface(){}
virtual void TimerCallback(int nTimerID) = 0;
};
class myDailyTimer :
public myThread
{
public:
boost::asio::io_service m_IO;
boost::asio::deadline_timer * m_pTimer;
tm m_tmSpecificTime;
std::string m_strSpecificTime;
int m_nTimerID;
myDailyTimerInterface* m_pParent;
public:
myDailyTimer();
~myDailyTimer();
void SetTime(tm strIN, int nID); // msec
void TimerCallback();
//Override
void ThreadMain();
protected:
std::string MakeStringSpecificTime();
void AddOneDay();
};
myDailyTimer.cpp
myDailyTimer::myDailyTimer()
{
m_pTimer = 0;
m_strSpecificTime = "";
}
myDailyTimer::~myDailyTimer()
{
EndThread();
if (m_pTimer != 0)
{
m_pTimer->cancel();
delete m_pTimer;
}
m_IO.stop();
m_IO.~io_service();
int i = 0;
i++;
}
void myDailyTimer::SetTime(tm tmIN, int nID) // msec
{
if (m_pTimer != 0)
{
m_pTimer->cancel();
delete m_pTimer;
}
m_tmSpecificTime = tmIN;
m_strSpecificTime = MakeStringSpecificTime();
m_nTimerID = nID;
m_pTimer = new boost::asio::deadline_timer(m_IO, boost::posix_time::time_from_string(m_strSpecificTime));
m_pTimer->async_wait(boost::bind(&myDailyTimer::TimerCallback, this));
myThread::Start();
}
std::string myDailyTimer::MakeStringSpecificTime()
{
time_t localTime;
localTime = mktime(&m_tmSpecificTime); // time is GMT local
struct tm * ptm = gmtime(&localTime); // convert time to GMT +0
char veccNextTime[64];
memset(veccNextTime, 0, sizeof(veccNextTime));
sprintf(veccNextTime, "%d-%02d-%02d %02d:%02d:%02d.000",
ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
std::string strTemp(veccNextTime);
return strTemp;
}
void myDailyTimer::AddOneDay()
{
m_tmSpecificTime.tm_mday += 1;
mktime(&m_tmSpecificTime); /* normalize result */
}
void myDailyTimer::TimerCallback()
{
if (m_pParent != 0)
m_pParent->TimerCallback(m_nTimerID);
//m_timer->expires_from_now(boost::posix_time::milliseconds(m_nTimerDuration));
AddOneDay();
m_strSpecificTime = MakeStringSpecificTime();
m_pTimer->expires_at(boost::posix_time::time_from_string(m_strSpecificTime));
m_pTimer->async_wait(boost::bind(&myDailyTimer::TimerCallback, this));
}
//Override
void myDailyTimer::ThreadMain()
{
while (!IsEndThread())
m_IO.run();
int j = 0;
j++;
}
As Dan Mašek mentioned, explicitly calling the destructor isn't a good pattern here. The standard way to stop an io_service is to stop every "work" that is pending and then wait for io_service::run function to return. Also, to prevent the io_service::run function from returning prematurely, it is a good idea to create an instance of io_service::work object.
Hope you'll be able to modify this example to your use case:
namespace asio = boost::asio;
class MyTimer {
using Clock = std::chrono::steady_clock;
public:
MyTimer(Clock::duration duration)
: _work(_ios)
, _timer(_ios)
, _thread([this] { _ios.run(); })
{
_ios.post([this, duration] { start(duration); });
}
~MyTimer() {
_ios.post([this] { stop(); });
_thread.join();
}
private:
void start(Clock::duration duration) {
_timer.expires_from_now(duration);
_timer.async_wait([this](boost::system::error_code) {
// NOTE: Be careful here as this is run from inside
// the thread.
if (!_work) {
// Already stopped.
std::cout << "Stopped" << std::endl;
return;
}
std::cout << "Timer fired" << std::endl;
});
}
void stop() {
_work.reset();
_timer.cancel();
}
private:
asio::io_service _ios;
boost::optional<asio::io_service::work> _work;
asio::steady_timer _timer;
std::thread _thread;
};
int main() {
auto* my_timer = new MyTimer(std::chrono::seconds(1));
delete my_timer;
return 0;
}

Threaded timer, interrupting a sleep (stopping it)

I'm wanting a reasonably reliable threaded timer, so I've written a timer object that fires a std::function on a thread. I would like to give this timer the ability to stop before it gets to the next tick; something you can't do with ::sleep (at least I don't think you can).
So what I've done is put a condition variable on a mutex. If the condition times out, I fire the event. If the condition is signalled the thread is exited. So the Stop method needs to be able to get the thread to stop and/or interrupt its wait, which I think is what it's doing right now.
There are problems with this however. Sometimes the thread isn't joinable() and sometimes the condition is signalled after its timeout but before it's put into its wait state.
How can I improve this and make it robust?
The following is a full repo. The wait is 10 seconds here but the program should terminate immediately as the Foo is created and then immediately destroyed. It does sometimes but mostly it does not.
#include <atomic>
#include <thread>
#include <future>
#include <sstream>
#include <chrono>
#include <iostream>
class Timer
{
public:
Timer() {}
~Timer()
{
Stop();
}
void Start(std::chrono::milliseconds const & interval, std::function<void(void)> const & callback)
{
Stop();
thread = std::thread([=]()
{
for(;;)
{
auto locked = std::unique_lock<std::mutex>(mutex);
auto result = terminate.wait_for(locked, interval);
if (result == std::cv_status::timeout)
{
callback();
}
else
{
return;
}
}
});
}
void Stop()
{
terminate.notify_one();
if(thread.joinable())
{
thread.join();
}
}
private:
std::thread thread;
std::mutex mutex;
std::condition_variable terminate;
};
class Foo
{
public:
Foo()
{
timer = std::make_unique<Timer>();
timer->Start(std::chrono::milliseconds(10000), std::bind(&Foo::Callback, this));
}
~Foo()
{
}
void Callback()
{
static int count = 0;
std::ostringstream o;
std::cout << count++ << std::endl;
}
std::unique_ptr<Timer> timer;
};
int main(void)
{
{
Foo foo;
}
return 0;
}
See my comment. You forgot to implement the state of the thing the thread is waiting for, leaving the mutex nothing to protect and the thread nothing to wait for. Condition variables are stateless -- your code must track the state of the thing whose change you're notifying the thread about.
Here's the code fixed. Notice that the mutex protects stop, and stop is the thing the thread is waiting for.
class Timer
{
public:
Timer() {}
~Timer()
{
Stop();
}
void Start(std::chrono::milliseconds const & interval,
std::function<void(void)> const & callback)
{
Stop();
{
auto locked = std::unique_lock<std::mutex>(mutex);
stop = false;
}
thread = std::thread([=]()
{
auto locked = std::unique_lock<std::mutex>(mutex);
while (! stop) // We hold the mutex that protects stop
{
auto result = terminate.wait_for(locked, interval);
if (result == std::cv_status::timeout)
{
callback();
}
}
});
}
void Stop()
{
{
// Set the predicate
auto locked = std::unique_lock<std::mutex>(mutex);
stop = true;
}
// Tell the thread the predicate has changed
terminate.notify_one();
if(thread.joinable())
{
thread.join();
}
}
private:
bool stop; // This is the thing the thread is waiting for
std::thread thread;
std::mutex mutex;
std::condition_variable terminate;
};

Simple SDL_GetTimer() usage - why isn't it working?

I've tried to use SDL_GetTimer() to make action after passing 1000ms using this piece of code:
while(1)
{
int tajmer;
int czas = SDL_GetTicks();
tajmer = SDL_GetTicks() - czas;
if(tajmer > 1000)
{
MoveUp();
czas = SDL_GetTicks();
}
}
But it causes my program to crash. Any ideas why, or how to implement simple timer correctly?
Every time the loop runs, czas is updated to the current time.
Solution: Move it out of the loop.
int czas = SDL_GetTicks();
while(1)
{
int tajmer;
tajmer = SDL_GetTicks() - czas;
if(tajmer > 1000)
{
MoveUp();
czas = SDL_GetTicks();
}
}
However what you are trying to accomplish could possibly be done in a better way using built in timers:
http://wiki.libsdl.org/SDL_AddTimer
Edit:
Example using SDL_AddTimer.
Uint32 my_callbackfunc(Uint32 interval, void *param);
int main() {
... // don't forget to SDL_Init
...
SDL_AddTimer(1000, my_callbackfunc, NULL);
...
}
Uint32 my_callbackfunc(Uint32 interval, void *param)
{
MoveUp();
return(1000); // or however long to wait before my_callbackfunc should run.
}
If you are currently using classes and want to call a class's method called MoveUp() then perhaps:
class example {
...
void start_moving() {
SDL_AddTimer(1000, my_callbackfunc, (void*)this);
}
...
public void MoveUp() {
...
}
}
Uint32 my_callbackfunc(Uint32 interval, void *param) {
((example*)param)->MoveUp();
return (1000);
}
Continuing on Yujin Wus answer you can also do something like this.
int timer = 0;
int ticks = SDL_GetTicks();
while(true)
{
timer += SDL_GetTicks() - ticks;
ticks = SDL_GetTicks();
if(timer >= 1000)
{
timer -= 1000;
MoveUp();
}
}
Or something like this
const int DELAY = 1000;
int timer = SDL_GetTicks() + DELAY;
while(true)
{
if(timer - SDL_GetTicks() <= 0)
{
timer += DELAY;
MoveUp();
}
}

How to create timer events using C++ 11?

How to create timer events using C++ 11?
I need something like: “Call me after 1 second from now”.
Is there any library?
Made a simple implementation of what I believe to be what you want to achieve. You can use the class later with the following arguments:
int (milliseconds to wait until to run the code)
bool (if true it returns instantly and runs the code after specified time on another thread)
variable arguments (exactly what you'd feed to std::bind)
You can change std::chrono::milliseconds to std::chrono::nanoseconds or microseconds for even higher precision and add a second int and a for loop to specify for how many times to run the code.
Here you go, enjoy:
#include <functional>
#include <chrono>
#include <future>
#include <cstdio>
class later
{
public:
template <class callable, class... arguments>
later(int after, bool async, callable&& f, arguments&&... args)
{
std::function<typename std::result_of<callable(arguments...)>::type()> task(std::bind(std::forward<callable>(f), std::forward<arguments>(args)...));
if (async)
{
std::thread([after, task]() {
std::this_thread::sleep_for(std::chrono::milliseconds(after));
task();
}).detach();
}
else
{
std::this_thread::sleep_for(std::chrono::milliseconds(after));
task();
}
}
};
void test1(void)
{
return;
}
void test2(int a)
{
printf("%i\n", a);
return;
}
int main()
{
later later_test1(1000, false, &test1);
later later_test2(1000, false, &test2, 101);
return 0;
}
Outputs after two seconds:
101
The asynchronous solution from Edward:
create new thread
sleep in that thread
do the task in that thread
is simple and might just work for you.
I would also like to give a more advanced version which has these advantages:
no thread startup overhead
only a single extra thread per process required to handle all timed tasks
This might be in particular useful in large software projects where you have many task executed repetitively in your process and you care about resource usage (threads) and also startup overhead.
Idea: Have one service thread which processes all registered timed tasks. Use boost io_service for that.
Code similar to:
http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/tutorial/tuttimer2/src.html
#include <cstdio>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(1));
t.async_wait([](const boost::system::error_code& /*e*/){
printf("Printed after 1s\n"); });
boost::asio::deadline_timer t2(io, boost::posix_time::seconds(1));
t2.async_wait([](const boost::system::error_code& /*e*/){
printf("Printed after 1s\n"); });
// both prints happen at the same time,
// but only a single thread is used to handle both timed tasks
// - namely the main thread calling io.run();
io.run();
return 0;
}
Use RxCpp,
std::cout << "Waiting..." << std::endl;
auto values = rxcpp::observable<>::timer<>(std::chrono::seconds(1));
values.subscribe([](int v) {std::cout << "Called after 1s." << std::endl;});
This is the code I have so far:
I am using VC++ 2012 (no variadic templates)
//header
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <chrono>
#include <memory>
#include <algorithm>
template<class T>
class TimerThread
{
typedef std::chrono::high_resolution_clock clock_t;
struct TimerInfo
{
clock_t::time_point m_TimePoint;
T m_User;
template <class TArg1>
TimerInfo(clock_t::time_point tp, TArg1 && arg1)
: m_TimePoint(tp)
, m_User(std::forward<TArg1>(arg1))
{
}
template <class TArg1, class TArg2>
TimerInfo(clock_t::time_point tp, TArg1 && arg1, TArg2 && arg2)
: m_TimePoint(tp)
, m_User(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2))
{
}
};
std::unique_ptr<std::thread> m_Thread;
std::vector<TimerInfo> m_Timers;
std::mutex m_Mutex;
std::condition_variable m_Condition;
bool m_Sort;
bool m_Stop;
void TimerLoop()
{
for (;;)
{
std::unique_lock<std::mutex> lock(m_Mutex);
while (!m_Stop && m_Timers.empty())
{
m_Condition.wait(lock);
}
if (m_Stop)
{
return;
}
if (m_Sort)
{
//Sort could be done at insert
//but probabily this thread has time to do
std::sort(m_Timers.begin(),
m_Timers.end(),
[](const TimerInfo & ti1, const TimerInfo & ti2)
{
return ti1.m_TimePoint > ti2.m_TimePoint;
});
m_Sort = false;
}
auto now = clock_t::now();
auto expire = m_Timers.back().m_TimePoint;
if (expire > now) //can I take a nap?
{
auto napTime = expire - now;
m_Condition.wait_for(lock, napTime);
//check again
auto expire = m_Timers.back().m_TimePoint;
auto now = clock_t::now();
if (expire <= now)
{
TimerCall(m_Timers.back().m_User);
m_Timers.pop_back();
}
}
else
{
TimerCall(m_Timers.back().m_User);
m_Timers.pop_back();
}
}
}
template<class T, class TArg1>
friend void CreateTimer(TimerThread<T>& timerThread, int ms, TArg1 && arg1);
template<class T, class TArg1, class TArg2>
friend void CreateTimer(TimerThread<T>& timerThread, int ms, TArg1 && arg1, TArg2 && arg2);
public:
TimerThread() : m_Stop(false), m_Sort(false)
{
m_Thread.reset(new std::thread(std::bind(&TimerThread::TimerLoop, this)));
}
~TimerThread()
{
m_Stop = true;
m_Condition.notify_all();
m_Thread->join();
}
};
template<class T, class TArg1>
void CreateTimer(TimerThread<T>& timerThread, int ms, TArg1 && arg1)
{
{
std::unique_lock<std::mutex> lock(timerThread.m_Mutex);
timerThread.m_Timers.emplace_back(TimerThread<T>::TimerInfo(TimerThread<T>::clock_t::now() + std::chrono::milliseconds(ms),
std::forward<TArg1>(arg1)));
timerThread.m_Sort = true;
}
// wake up
timerThread.m_Condition.notify_one();
}
template<class T, class TArg1, class TArg2>
void CreateTimer(TimerThread<T>& timerThread, int ms, TArg1 && arg1, TArg2 && arg2)
{
{
std::unique_lock<std::mutex> lock(timerThread.m_Mutex);
timerThread.m_Timers.emplace_back(TimerThread<T>::TimerInfo(TimerThread<T>::clock_t::now() + std::chrono::milliseconds(ms),
std::forward<TArg1>(arg1),
std::forward<TArg2>(arg2)));
timerThread.m_Sort = true;
}
// wake up
timerThread.m_Condition.notify_one();
}
//sample
#include <iostream>
#include <string>
void TimerCall(int i)
{
std::cout << i << std::endl;
}
int main()
{
std::cout << "start" << std::endl;
TimerThread<int> timers;
CreateTimer(timers, 2000, 1);
CreateTimer(timers, 5000, 2);
CreateTimer(timers, 100, 3);
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "end" << std::endl;
}
If you are on Windows, you can use the CreateThreadpoolTimer function to schedule a callback without needing to worry about thread management and without blocking the current thread.
template<typename T>
static void __stdcall timer_fired(PTP_CALLBACK_INSTANCE, PVOID context, PTP_TIMER timer)
{
CloseThreadpoolTimer(timer);
std::unique_ptr<T> callable(reinterpret_cast<T*>(context));
(*callable)();
}
template <typename T>
void call_after(T callable, long long delayInMs)
{
auto state = std::make_unique<T>(std::move(callable));
auto timer = CreateThreadpoolTimer(timer_fired<T>, state.get(), nullptr);
if (!timer)
{
throw std::runtime_error("Timer");
}
ULARGE_INTEGER due;
due.QuadPart = static_cast<ULONGLONG>(-(delayInMs * 10000LL));
FILETIME ft;
ft.dwHighDateTime = due.HighPart;
ft.dwLowDateTime = due.LowPart;
SetThreadpoolTimer(timer, &ft, 0 /*msPeriod*/, 0 /*msWindowLength*/);
state.release();
}
int main()
{
auto callback = []
{
std::cout << "in callback\n";
};
call_after(callback, 1000);
std::cin.get();
}
I'm looking for a simple solution and everything I found is too long and complicated. After reading the documentation, I found that this can be done in just a few lines of code.
This question may be old but can beneficial to future researchers.
Example: Set isContinue to false if you want to stop the thread.
#include <chrono>
#include <thread>
volatile bool isContinue = true;
void NameOfYourFunction(){
while(continue){
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); //sleep for 1 seconds
//do something here after every 1 seconds...
}
}
int main(){
std::thread your_thread(NameOfYourFunction); // Register your `YourFunction`.
your_thread.detach(); // this will be non-blocking thread.
//your_thread.join(); // this will be blocking thread.
}
use detach() or join() depending on your situation.
When using detach(), the execution main thread continues running.
When using join(), the execution main thread pauses and waits until
the new thread ends.