I want to implement some system in c++ so that I can call a function and ask for another function to be called in X milliseconds. Something like this:
callfunctiontimed(25, funcName);
25 being the amount of milliseconds before the function should be called.
I would like to know if multithreading is required for this and then use some delay function? Other than using function pointer how would a feature like this work?
The timer object supports properties that let you specify the MATLAB® commands that execute when a timer fires, and for other timer object events, such as starting, stopping, or when an error occurs. These are called callbacks.
A callback is any executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at a given time [Source : Wiki]. In simple language, If a reference of a function is passed to another function as an argument to call it, then it will be called as a Callback function.
Callback functions are an essential and often critical concept that developers need to create drivers or custom libraries. A callback function is a reference to executable code that is passed as an argument to other code that allows a lower-level software layer to call a function defined in a higher-level layer(10).
For a portable solution, you can use boost::asio. Below is a demo I wrote a while ago. You can change
t.expires_from_now(boost::posix_time::seconds(1));
to suit you need say make function call after 200 milliseonds.
t.expires_from_now(boost::posix_time::milliseconds(200));
Below is a complete working example. It's calling repeatedly but I think it should be easy to call only once by just change a bit.
#include <iostream>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::asio;
using namespace std;
class Deadline
{
public:
Deadline(deadline_timer &timer) : t(timer) {
wait();
}
void timeout(const boost::system::error_code &e) {
if (e)
return;
cout << "tick" << endl;
wait();
}
void cancel() {
t.cancel();
}
private:
void wait() {
t.expires_from_now(boost::posix_time::seconds(1)); //repeat rate here
t.async_wait(boost::bind(&Deadline::timeout, this, boost::asio::placeholders::error));
}
deadline_timer &t;
};
class CancelDeadline {
public:
CancelDeadline(Deadline &d) :dl(d) { }
void operator()() {
string cancel;
cin >> cancel;
dl.cancel();
return;
}
private:
Deadline &dl;
};
int main()
{
io_service io;
deadline_timer t(io);
Deadline d(t);
CancelDeadline cd(d);
boost::thread thr1(cd);
io.run();
return 0;
}
//result:
//it keeps printing tick every second until you enter cancel and enter in the console
tick
tick
tick
Do you want it to by asynchronous so that the callback gets executed when 25 miliseconds are over without blocking the main executing thread? If so, you can execute the callback in a separate thread from the timer / timed callback function you implement.
If you do not use multithreading, then your main or the calling function of callfunctiontimed(25, funcName); would block while you run a sleep / usleep. It is your choice now as to what behavior you want to implement.
The real solution would not be as simple as to multithread or not. There are things like, how do you keep different timers/callbacks information considering the function can be called multiple times with different timeouts and functions.
One way to do it, would be like this:
As the timer thread is done sleeping, it removes and looks at head of the list and executes the function pointer in a new thread. Timer thread is re-initialized with sleep time on the new head of the list.
main() {
//spawn a timer thread with pthread create
callfunctiontimed(25, test);
callfunctiontimed(35, show);
callfunctiontimed(4, print);
}
callfunctionTImed(int time, (func*)function, void*data) //
{
//add information to sorted list of timer and callbacks
//re-initialize sleep_time for timer thread if needed.
return.
}
timerThread() {
while(1){
sleep(sleep_time);
//look at head of timer list, remove it, call function in a new thread
//adjust sleep time as per new head
}
}
Hopefully this gives an idea of what I meant, although this is not perfect and has several problems.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With