This is a light-weight, header-only C++ Timer-alarm library that's based on threads as opposed to the POSIX' signal based timers. Therefore, it is a lot less disruptive.
It has the following logic:
- It is templated with a class (functor) type. The functor (F) must define the
opperator()()
. - You instantiate an instance of TimerAlarm by calling the constructor and passing:
- A reference to an instance of the functor
- The second part of the time interval
- The nano-second part of the time interval. It is 0 by default
- The repeat count which specifies how many times the timer should repeat itself. It is set to
FOREVER
by default.
- You can
arm()
the TimerAlarm instance. That means the timer-alarm will now be in effect. Once armed one thread will be created to run the timer. The thread is never destroyed and reused repeatedly. - You can
disarm()
the TimerAlarm instance. That means the timer will no longer execute. The thread is destroyed at this time but not before it is finished. - You can always change the interval period by calling
set_time_interval()
. - You can query if the timer is armed by calling
is_armed()
. - You can query how many times the functor has been executed by calling
current_repeat_count()
. - The destructor waits until all timer invocations are done.
class MyFoot {
public:
MyFoot (int id) : id_ (id), count_ (0) { }
bool operator ()() {
std::cout << "Printing from MyFoot (" << id_ << "). count is "
<< count_ << ". time is " << time(nullptr) << std::endl;
count_ += 1;
return (true);
}
private:
int id_;
size_t count_;
};
// ----------------------------------------------------------------------------
int main(int, char *[]) {
const struct ::timespec rqt = { 60, 0 };
{
MyFoot foot_master (10);
// The functor foot_master must be executed every 5 seconds
// "interval_nanosec" is set to zero by default.
// "repeat_count" is set to forever by default
//
TimerAlarm<MyFoot> timer (foot_master, 5);
// The Timer will be armed
//
timer.arm();
const struct ::timespec rqt2 = { 30, 0 };
nanosleep(&rqt2, nullptr);
// Change the interval to 1 seconds.
// "interval_nanosec" is set to zero by default.
//
timer.set_time_interval(1);
nanosleep(&rqt2, nullptr);
// Change the interval to 10 seconds.
// "interval_nanosec" is set to zero by default.
//
timer.set_time_interval(10);
nanosleep(&rqt, nullptr);
MyFoot foot_master2 (200);
// Construct a second timer with specifed parameters.
//
TimerAlarm<MyFoot> timer2 (foot_master2, // Functor instance
5, // 5 seconds intervals
0, // 0 nano-seconds specified
TimerAlarm<MyFoot>::FOREVER); // Repeat forever
timer2.arm(); // Armed timer will execute
nanosleep(&rqt, nullptr);
}
std::cout << "\n\nmain(): Got out of the enclosing block ...\n" << std::endl;
MyFoot foot_master (3000);
// Construct a third timer with specifed parameters.
//
TimerAlarm<MyFoot> timer (foot_master, // Functor instance
5, // 5 seconds intervals
0, // 0 nano-seconds specified
5); // Repeat 5 times
timer.arm(); // Armed timer will execute
nanosleep(&rqt, nullptr);
return (EXIT_SUCCESS);
}