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

 

posted @ 2024-12-23 11:27  墨尔基阿德斯  阅读(119)  评论(0)    收藏  举报