c++实现定时回调函数

2022-01-03 00:00:00 function-pointers callback timing c++

我想用 C++ 实现一些系统,以便我可以调用一个函数并要求在 X 毫秒内调用另一个函数.像这样:

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 是应调用函数之前的毫秒数.

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?

推荐答案

很多人都在这里提供了很好的答案,但我会直接解决这个问题,因为几年前我也遇到过类似的问题.我无法使用 Boost 有几个原因――我知道 Boost 在很多开源软件中都有很好的用途.此外,我真的很想理解计时器和回调,因为它们与基于 Linux 的环境有关.所以,我自己写了.

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.

从根本上说,我有一个 Timer 类和一个 TimerCallback 类.一个典型的回调,作为TimerCallback 类的继承类实现,会将回调时要执行的操作放在triggered() 方法中,专门针对需求实现.

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.

根据通常的语义,Timer 对象与回调对象相关联,该对象可能包含执行回调所需的所有必需信息.定时器调度由一个环境范围的定时器 minheap 管理,它必须在一个单独的线程/进程中维护.这个 minheap 任务只做一件事:它对未来设置的回调事件的 minheap 进行 minheapizing.minheap 在 O(1) 中选择下一个要触发的事件,并且可以在 O(log n) 中为 n 个计时器事件对剩余的事件进行 minheapify.它还可以在 O(log n) 中插入一个新的计时器事件(阅读堆简介 这里).

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).

当定时器触发时,minheap 调度器会检查它是周期性定时器、单次定时器还是执行特定次数的定时器.因此,定时器对象要么从 minheap 中移除,要么在下一个执行时间重新插入 minheap.如果要删除一个计时器对象,则将其从 minheap 中删除(但计时器对象的删除可能会或可能不会留给创建它的任务)并且堆的其余部分被 minheap 化;即,重新排列以满足 minheap 属性.

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.

一个工作和单元测试的实现是这里,并且可能包含错误(摘自我的应用程序),但我认为它可以帮助某人.实现是基于多进程(fork()ed-process)的(也在主任务(进程)中使用pthreads),并使用POSIX共享内存和用于进程间通信的 POSIX 消息队列.

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.

相关文章