C++ 定时器,时间轮算法
C++ 实现定时器的两种方法(线程定时和时间轮算法修改版)_c++ 定时器-CSDN博客
原版addtask函数有bug,修改了下
#ifndef ZROS_TIMER_HPP_
#define ZROS_TIMER_HPP_
#include <chrono>
#include <functional>
#include <list>
#include <mutex>
#include <thread>
#include <vector>
class TimerWheel {
public:
using Task = std::function<void(int32_t pub_index)>;
struct TaskWithParam
{
Task task;
int32_t pub_index;//参数
};
explicit TimerWheel(size_t wheel_size, int interval_micros)
: wheel_size_(wheel_size),
interval_micros_(interval_micros),
wheel_(wheel_size),
current_index_(0) {
std::cerr << "wheel_size:" << wheel_size << " interval_micros:" << interval_micros << std::endl;
}
~TimerWheel() {
Stop();
}
void Start() {
if (running_) {
return;
}
running_ = true;
thread_ = std::thread([this]() {
while (running_) {
std::this_thread::sleep_for(std::chrono::microseconds(interval_micros_));
Tick();
}
std::cerr << "timer oooops!" << std::endl;
});
thread_.detach();
}
void Stop() {
if (!running_) {
return;
}
running_ = false;
if (thread_.joinable()) {
thread_.join();
}
}
void AddTask(int timeout_micros, TaskWithParam &&task) {
std::lock_guard<std::mutex> lock(mutex_);
size_t ticks = timeout_micros / interval_micros_;
if (ticks == 0)
{
ticks = 1;
}
size_t index = (current_index_ + ticks) % wheel_size_;
size_t allindex = index;
wheel_[allindex].push_back(task);
while (allindex < wheel_size_)
{
wheel_[allindex].push_back(task);
allindex += ticks;
}
}
private:
void Tick() {
std::lock_guard<std::mutex> lock(mutex_);
auto& tasks = wheel_[current_index_];
for (const auto& task : tasks) {
task.task(task.pub_index);
}
//tasks.clear();
current_index_ = (current_index_ + 1) % wheel_size_;
}
private:
size_t wheel_size_;
int interval_micros_;
std::vector<std::list<TaskWithParam>> wheel_;
size_t current_index_;
bool running_ = false;
std::thread thread_;
std::mutex mutex_;
};
#endif