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

C++模擬實(shí)現(xiàn)時(shí)間輪模式(推薦)

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

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

其主要框架圖為:

1、具體實(shí)現(xiàn)方式:

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

2、定時(shí)器任務(wù)類

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

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

相關(guān)文章

最新評(píng)論

东阳市| 商城县| 建昌县| 吴桥县| 民权县| 陕西省| 北流市| 关岭| 锡林浩特市| 阳新县| 嘉义县| 灵丘县| 玉山县| 体育| 清徐县| 辽宁省| 江西省| 嘉黎县| 临泽县| 梁河县| 峨眉山市| 昭苏县| 白水县| 高邑县| 吉隆县| 抚州市| 克什克腾旗| 田阳县| 焦作市| 和林格尔县| 呼和浩特市| 娱乐| 西安市| 镇远县| 乐至县| 班玛县| 宁明县| 新余市| 宝清县| 云龙县| 大丰市|