Search code examples
c++callbackfunction-pointerstiming

c++ Implementing Timed Callback function


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?


Solution

  • Many folks have contributed good answers here on the matter, but I will address the question directly, because I had a similar problem a couple of years ago. I could not use Boost for several reasons--I know Boost has excellent use in a lot of open source software. Moreover, I really wanted to understand timers and callbacks specifically as it pertains to Linux based environments. So, I wrote my own.

    Fundamentally, I have a Timer class and a TimerCallback class. A typical callback, implemented as a inherited class of the TimerCallback class, will place the operations to be executed upon callback in the triggered () method, implemented specifically for the needs.

    Per the usual semantics, a Timer object is associated with a callback object, which presumably contains all the required information needed for the callback to execute. The timer scheduling is managed by one environment-wide timer minheap which has to be maintained in a separate thread/process. This minheap task does only one thing: it minheapifies the minheap of callback events set in the future. A minheap selects the next event to fire in O(1) and can minheapify the remaining in O(log n) for n timer events. It can also insert a new timer event in O(log n) (Read a gentle introduction to heaps here).

    When a timer fires, the minheap scheduler checks if it is a periodic timer, one shot timer or a timer that will execute a specific number of times. Accordingly, the timer object is either removed from the minheap or reinserted back into the minheap with the next execution time. If a timer object is to be removed, then it is removed from the minheap (but the timer object deletion may or may not be left to the task that created it) and the rest of the heap is minheap-ified; i.e., rearranged to satisfy the minheap property.

    A working and unit tested implementation is here, and may contain bugs (excerpted from my application), but I thought it may help someone. The implementation is multi-process (fork()ed-process) based (and also uses pthreads in the main task (process)), and uses POSIX shared memory and POSIX message queues for communication between the processes.