最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++模擬實現時間輪模式(推薦)

 更新時間:2025年11月27日 09:59:23   作者:是小胡嘛  
文章介紹了時間輪(TimerWheel)的原理和實現方式,這是一種高效的定時器管理算法,常用于操作系統(tǒng)內核,時間輪通過類似鐘表的機制管理定時任務,每過一秒,秒針移動一格,觸發(fā)相應任務,感興趣的朋友跟隨小編一起看看吧

時間輪(TimerWheel) 是一種非常經典且高效的定時器管理算法,廣泛應用于操作系統(tǒng)內核。就像墻上的鐘,表盤上的60個小格子上面掛著這一秒要做的任務,而秒針每一秒走一格。

其主要框架圖為:

1、具體實現方式:

/**
 * @brief 時間輪類
 * 通過循環(huán)數組管理定時任務,模擬時鐘轉動。
 */
class TimerWheel{
    private:
        using WeakTask = std::weak_ptr<TimerTask>;
        using PtrTask = std::shared_ptr<TimerTask>;
        int _tick;//當前的秒針,走到哪里釋放哪里,釋放哪里就相當于執(zhí)行哪里的任務
        int _capacity;//表盤最大數量--其實就是最大延遲時間
        // 時間輪槽位:每個槽位是一個數組,存放該秒需要處理(或存活)的任務的 shared_ptr
        // 只要 shared_ptr 在這個數組里,引用計數就 > 0,任務就不會析構。
        std::vector<std::vector<PtrTask>> _wheel;
        // 索引表:通過 ID 快速找到任務對象。
        // 使用 weak_ptr 是為了不增加引用計數,避免干擾生命周期管理。
        std::unordered_map<uint64_t,WeakTask> _timers;
    private:
        // 從索引表中移除定時器記錄
        void RemoveTimer(uint64_t id){
            auto it = _timers.find(id);
            if(it != _timers.end()){
                _timers.erase(it);
            }
        } 
    public:
        TimerWheel():_capacity(60),_tick(0),_wheel(_capacity){}
        /**
         * @brief 添加定時任務
         * @param id 任務ID
         * @param delay 延遲多少秒執(zhí)行
         * @param cb 任務回調
         */
        void TimerAdd(uint64_t id,uint32_t delay,const TaskFunc &cb){
            // 1. 創(chuàng)建新任務對象,引用計數初始化為 1
            PtrTask pt(new TimerTask(id,delay,cb));
            // 2. 綁定 Release 回調,讓 Task 析構時能把自己從 _timers 里面刪掉
            pt->SetRelease(std::bind(&TimerWheel::RemoveTimer,this,id));
            // 3. 計算放置在時間輪的哪個槽位
            // 比如當前 tick 是 0,延遲 5 秒,則放在下標 5 的位置
            int pos = (_tick+delay)%_capacity;
            // 4. 將 shared_ptr 放入對應的槽位(引用計數 +1)
            _wheel[pos].push_back(pt);
            // 5. 記錄到索引表(weak_ptr 不增加引用計數)
            _timers[id] = WeakTask(pt);
        }
        /**
         * @brief 刷新定時任務(續(xù)命)
         * 類似于 TCP 的 KeepAlive,如果連接有活動,就重置它的超時時間。
         */
        void TimerRefresh(uint64_t id){
            auto it = _timers.find(id);
            if(it == _timers.end()){
                return;//沒找到定時任務
            }
            // 2. 嘗試將 weak_ptr 提升為 shared_ptr
            // 如果對象還沒析構,pt 就不為空
            PtrTask pt = it->second.lock();
            // 3. 重新計算新的槽位
            int delay = pt->DelayTime();
            int pos = (_tick + delay)%_capacity;
            // 4. 將 shared_ptr 再次加入新槽位
            // 注意:此時該任務對象可能同時存在于多個槽位中(舊槽位和新槽位)。
            // 只要還有一個槽位持有它,引用計數就不為0,它就不會析構。
            _wheel[pos].push_back(pt);
        }
        /**
         * @brief 取消定時任務
         */
        void TimerCancel(uint64_t id){
            auto it = _timers.find(id);
            if(it == _timers.end()){
                return;//沒找到定時任務
            }
            PtrTask pt = it->second.lock();
            if(pt)pt->Cancel();// 僅僅設置標志位,等待自然析構時不執(zhí)行回調
        }
        /**
         * @brief 驅動時間輪走動一格
         * 通常由一個每秒觸發(fā)一次的定時器(如 timerfd)調用
         */
        void RunTimerTask(){
            // 1. 秒針向前走一步
            _tick = (_tick + 1)%_capacity;
            // 2. 清空當前秒針指向的槽位
            // vector::clear() 會析構里面所有的 shared_ptr。
            // 如果某個 Task 的引用計數因此減為 0,就會調用 ~TimerTask(),從而執(zhí)行任務。
            // 如果該 Task 之前被 Refresh 過,它還會存在于后續(xù)的槽位中,引用計數 > 0,這里 clear 不會導致它析構。
            _wheel[_tick].clear();//清空指定位置的數組
        }
};

2、定時器任務類

/**
 * @brief 定時器任務類
 * 封裝了一個具體的定時任務,利用 RAII 機制,
 * 當該對象被銷毀時(引用計數歸零),觸發(fā)任務執(zhí)行。
 */
class TimerTask{
    private:
        uint64_t _id;//定時器任務ID
        uint32_t _timeout;//定時器任務的超時時間(延遲時間)
        bool _canceled;//false 表示沒有被取消,true-表示被取消
        TaskFunc _task_cb;//定時器定時任務
        ReleaseFunc _release;//刪除TimerWheel中保存的定時器對象信息
    public:
        TimerTask(uint64_t id,uint32_t delay,const TaskFunc &cb):
            _id(id),_timeout(delay),_task_cb(cb){}
        /**
         * @brief 析構函數
         * 核心邏輯所在:當 shared_ptr 計數減為 0 時,對象析構。
         * 此時檢查是否被取消,如果沒有取消,則執(zhí)行定時任務。
         */
        ~TimerTask() {
            if (!_canceled && _task_cb) {
                _task_cb(); // 執(zhí)行任務
            }
            if (_release) {
                _release(); // 從時間輪的索引 map 中刪除自己
            }
        }
        // 設置任務取消狀態(tài)
        void Cancel(){_canceled = true;}
        // 設置清理回調(用于從 map 中移除記錄)
        void SetRelease(const ReleaseFunc &cb){_release = cb;}
        // 獲取延遲時間
        uint32_t DelayTime(){return _timeout;}
};

到此這篇關于C++模擬實現時間輪模式的文章就介紹到這了,更多相關C++時間輪模式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關文章

  • c語言實現向上取整計算方法

    c語言實現向上取整計算方法

    這篇文章主要介紹了c語言實現向上取整計算方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • c++ stack容器適配器的使用

    c++ stack容器適配器的使用

    在C++中,std::stack是一個標準模板庫中的容器適配器,它提供了一種后進先出的數據結構,本文主要介紹了c++ stack容器適配器的使用,具有一定的參考價值,感興趣的可以了解一下
    2024-05-05
  • C語言常見排序算法之插入排序(直接插入排序,希爾排序)

    C語言常見排序算法之插入排序(直接插入排序,希爾排序)

    這篇文章介紹C語言常見排序算法之插入排序(直接插入排序,希爾排序),主要分享介紹的是插入排序的兩種常用算法,直接插入排序和希爾排序,需要的朋友可以參考一下
    2022-07-07
  • C++中動態(tài)內存管理的實現

    C++中動態(tài)內存管理的實現

    本文主要介紹了C++中動態(tài)內存管理的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-09-09
  • 一篇文章帶你入門C語言:數組

    一篇文章帶你入門C語言:數組

    這篇文章主要介紹了C語言中數組的一些基本知識小結,其中重點是對于數組的內存分配相關方面的知識整理,需要的朋友可以參考下
    2021-08-08
  • C語言數組與地址、數組名到底是什么詳解

    C語言數組與地址、數組名到底是什么詳解

    在寫代碼的時候,我們經常用到數組,那么有沒有想過數組名是什么呢?這篇文章主要給大家介紹了關于C語言數組與地址、數組名到底是什么的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • 基于epoll的多線程網絡服務程序設計

    基于epoll的多線程網絡服務程序設計

    這篇文章主要為大家詳細介紹了基于epoll的多線程網絡服務程序設計,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Qt自制一個小鬧鐘的實現示例

    Qt自制一個小鬧鐘的實現示例

    本文主要介紹了Qt自制一個小鬧鐘的實現示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-09-09
  • Qt基礎開發(fā)之Qt文件操作類QFile讀寫文件的詳細方法與實例及QDataStream的使用方法

    Qt基礎開發(fā)之Qt文件操作類QFile讀寫文件的詳細方法與實例及QDataStream的使用方法

    這篇文章主要介紹了Qt基礎開發(fā)之Qt文件操作類QFile讀寫文件的詳細方法與實例,需要的朋友可以參考下
    2020-03-03
  • VC實現屏幕截詞功能的方法詳解

    VC實現屏幕截詞功能的方法詳解

    這篇文章主要介紹了VC實現屏幕截詞功能的方法詳解,對于深入的理解windows程序運行原理很有幫助,需要的朋友可以參考下
    2014-07-07

最新評論

伽师县| 仙居县| 郑州市| 渭南市| 巴里| 遂宁市| 昌图县| 涪陵区| 原阳县| 民权县| 金寨县| 左权县| 齐齐哈尔市| 梁山县| 石柱| 海伦市| 博乐市| 井陉县| 清涧县| 浏阳市| 门头沟区| 榆中县| 乐昌市| 河曲县| 板桥市| 佛山市| 抚宁县| 海晏县| 大邑县| 广丰县| 和田县| 合山市| 平阳县| 偏关县| 吴川市| 榆中县| 尚志市| 江津市| 和田市| 张家口市| 文化|