【C++】检测TCP链接超时——时间轮组件设计

目录

引言

时间轮思想

设计的核心思路

完整代码

组件接口


个人主页:东洛的克莱斯韦克-CSDN博客

引言

        对于高并发的服务器来说,链接是一种比较珍贵的资源,对不活跃的链接应该及时释放。判断连接是否活跃的策略是——在给定的时间内,该链接上并没有读事件,写事件,异常事件等。如果连接上有事件发生,则刷新链接的活跃时间。

        而时间轮就可以高效的检测链接是否活跃,本文会带大家封装出一个时间轮的组件。

时间轮思想

        时间轮的思想来源于钟表,钟表的时分秒指针指到特定的位置,就代表时间到了。参考钟表的策略,我们可用一个数组代表一个钟表,数组的下标代表时间,指向数组的指针按特定的时间向后移动,指针执行哪个位置,就代表哪个位置的时间到了。

        相应的,指针1秒向后走一格,数组大小为60,这就是分级的时间轮。指针1分钟向后走一格,数组大小为60,这就是时级的时间轮。指针1小时向后走一格,数组大小为24,这就是天级的时间轮。

        也就是说对于时间特别大的场景中,不需要很大的的空间。比如,一个任务在1天3小时15分5秒后超时(假设)只要天级时间轮指向1,就把该任务抛到时级时间轮中...以此类推。

设计的核心思路

        我们需要两个关键的技术——析构函数,智能指针shared_ptr。

【C++】智能指针——auto_ptr,unique_ptr,shared_ptr_auto ptr-CSDN博客

        在我们上述的阐述中,任务是有超时时间的,当时间轮的指针指向这个任务时,说明时间到了,我们该执行这个任务呢——答案是把任务的执行放到析构函数里。

        时间轮的容器可以用两层vevtor—— std::vector<std::vector<TaskSharedPtr>>。如果指针指向TaskSharedPtr(任务类),就释放该类,该类的析构函数就会指向任务的回调。两次vevtor表示在同一个时间内可能会有多个任务。

        智能指针shared_ptr用于任务类的超时时间刷新,在上文提到的高并发服务的场景中,如果触发了链接中的事件,就需要重新刷新时间,但时间轮的指针是一直向后移动的,任务类的下标迟早会被指到,然后该类就会被析构。

        那么我们可以用shared_ptr管理任务类,并且新shared_ptr被插入时间轮之后正确的位置,有shared_ptr的引用计数在,任务类就不会被析构,时间也相当于刷新了。

完整代码

#include <functional>
#include <vector>
#include <memory>
#include <unordered_map>
#include <iostream>
#include <unistd.h>using TaskFunk = std::function<void()>;  // 定时任务执行的方法
using CleanFunk = std::function<void()>; // 清理资源的回调
class TimerTask //任务类
{
private:uint64_t _id;        // 任务对象的唯一性标识uint32_t _timeout_t; // 任务的超时时间bool _cancel;        // 取消任务为true, 不取消为falseTaskFunk _taskfunk;  // 要执行的任务CleanFunk _cleanfunk;public:TimerTask(uint64_t id, uint32_t timeout_t, const TaskFunk &funk): _id(id), _timeout_t(timeout_t), _cancel(false), _taskfunk(funk){}~TimerTask(){if (_cancel == false){_taskfunk();}_cleanfunk();}void AddCleanFunk(const CleanFunk &func){_cleanfunk = func;}uint32_t GetTimeout() // 获取超时时间{return _timeout_t;}void CancelTask() // 取消任务{_cancel = true;}
};class TimerWheel //时间轮
{
private:using TaskSharedPtr = std::shared_ptr<TimerTask>;using TaskWeakPtr = std::weak_ptr<TimerTask>;size_t _ptr;                                    // 时间轮的指针size_t _capacity;                               // 时间轮的容量std::vector<std::vector<TaskSharedPtr>> _wheel; // 时间轮容器std::unordered_map<uint64_t, TaskWeakPtr> _v;   // 任务id和任务weak_ptr映射的容器,快速索引,使shared_ptr引用计数加一
private:void CleanV(uint64_t id) // 清理_v容器资源的函数{auto t = _v.find(id);if (t != _v.end()){_v.erase(id);}}public:TimerWheel(size_t capacity): _ptr(0), _capacity(capacity), _wheel(capacity){}void AddTimerTask(uint64_t id, uint32_t timeout_t, const TaskFunk &funk) // 添加定时任务{TaskSharedPtr sp(new TimerTask(id, timeout_t, funk));TaskWeakPtr wp = sp;_v[id] = wp;                                                // 向_v中注册sp->AddCleanFunk(std::bind(&TimerWheel::CleanV, this, id)); // 设置清理_v容器资源的回调size_t pos = (_ptr + sp->GetTimeout()) % _capacity;_wheel[pos].push_back(sp);}void UpdateTimerTask(uint64_t id) // 更新超时的时间{auto t = _v.find(id);if (t != _v.end()){TaskSharedPtr sp = _v[id].lock();size_t pos = (_ptr + sp->GetTimeout()) % _capacity;_wheel[pos].push_back(sp);}}void UpdatePtr() // 每隔?时间执行一次{_wheel[_ptr].clear();_ptr++;_ptr %= _capacity;}void CancelTask(uint64_t id) // 取消任务{auto t = _v.find(id);if (t != _v.end()){TaskSharedPtr sp = _v[id].lock();sp->CancelTask();}}
};

组件接口

AddTimerTask:向时间轮中注册任务,三个参数分别是任务id ,任务的超时时间,任务调用的方法。

在上层一定要确保任务id的唯一性。

UpdateTimerTask:传入任务id, 刷新超时时间

UpdatePtr: 这个接口就是前文说的时间轮的指针,多久调用一次就表示时间轮是一个什么级别的的时间轮

CancelTask:传入任务id,说明该任务在时间到了之后也不会被执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/433658.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis中BigKey与MoreKey优化笔记

1.MoreKey 在Redis中&#xff0c;MoreKey问题通常指的是当数据库中的key数量非常多时&#xff0c;使用如KEYS *这样的命令去检索所有的key&#xff0c;这会导致Redis服务阻塞&#xff0c;影响正常业务。因为Redis是单线程操作的&#xff0c;执行这类命令时会占用大量时间&…

Arthas redefine(加载外部的.class文件,redefine到JVM里 )

文章目录 二、命令列表2.2 class/classloader相关命令2.2.3 redefine&#xff08;加载外部的.class文件&#xff0c;redefine到JVM里 &#xff09;举例1&#xff1a;加载新的代码&#xff0c;jad/mc 命令使用举例2&#xff1a;上传 .class 文件到服务器的技巧 二、命令列表 2.…

柯桥韩语学校|韩语每日一词打卡:회갑연[회가변]【名词】花甲宴

今日一词:회갑연 韩语每日一词打卡&#xff1a;회갑연[회가변]【名词】花甲宴 原文:인구 노령화에 따라서 요즘 회갑연보다는 고희연을 더 많이 지냅니다. 意思&#xff1a;随着人口老龄化&#xff0c;最近比起花甲宴&#xff0c;更多人办古稀宴。 【原文分解】 1、인구[인구]…

【BurpSuite】访问控制漏洞和权限提升 | Access control vulnerabilities (3-6)

&#x1f3d8;️个人主页&#xff1a; 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞&#x1f44d;收藏&#x1f497;支持一下哦 【BurpSuite】访问控制漏洞和权限提升 | Access control vulnerabilities (3-6&#xff09; 实验三 Lab: User role controlled b…

【IoT-NTN】系统消息SIB31信令分析

3GPP卫星通信发展迅速&#xff0c; TS36.331 R17中新增SIB31携带星历信息&#xff0c;本文对SIB31的信令内容进行了分析。 SystemInformationBlockType31 分析报告 一、概述 本文档详细描述了SystemInformationBlockType31&#xff08;简称SIB31&#xff09;的结构和内容&am…

[Redis][集群][上]详细讲解

目录 0.前言1.基本概念2.数据分片算法0.前言1.哈希求余2.一致性哈希算法3.哈希槽分区算法(Redis使用) 0.前言 说明&#xff1a;该章节相关操作不需要记忆&#xff0c;理解流程和原理即可&#xff0c;用的时候能自主查到即可 1.基本概念 哨兵模式提高了系统的可用性&#xff0…

试用Debian12.7和Ubuntu24.4小札

Debian GNU/Linux 12 (bookworm)和Ubuntu 24.04.1 LTS是现阶段&#xff08;2024年9月26日&#xff09;两个发行版的最新版本。Ubuntu Server版本默认就不带桌面&#xff08;ubuntu-24.04-live-server-amd64.iso&#xff09;&#xff0c;这个默认就是最小化安装&#xff08;安装…

Moshi: a speech-text foundation model for real time dialogue

视频号 挺神奇的东西 整下来 kyutai-labs/moshi (github.com) git clone https://github.com/kyutai-labs/moshi.git 在线体验 moshi.chat 结束后 点击Download audio Download video 可以下载音频与视频 &#xff08;不过是webm格式&#xff09; 发行版 已上传至资源 小…

springboot+大数据基于数据挖掘的招聘信息可视化大屏系统【内含源码+文档+部署教程】

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

【C++】 vector 迭代器失效问题

【C】 vector 迭代器失效问题 一. 迭代器失效问题分析二. 对于vector可能会导致其迭代器失效的操作有&#xff1a;1. 会引起其底层空间改变的操作&#xff0c;都有可能是迭代器失效2. 指定位置元素的删除操作--erase3. Linux下&#xff0c;g编译器对迭代器失效的检测并不是非常…

数论——数数(找质因数个数),三位出题人(组合数学,快速幂)

数数&#xff08;找质因数个数&#xff09; 题目描述 登录—专业IT笔试面试备考平台_牛客网 运行代码&#xff08;通过率一半&#xff09; #include <iostream> #include <vector> using namespace std; const int N5e66; int n; vector<bool>vis; vo…

vmware-toolbox安装,VMware虚拟机访问win10共享目录

问题&#xff1a;VMware界面无法安装vmware-toolbox&#xff0c;共享目录设置失败 解决方法&#xff1a; VMware设置 共享文件夹 ubuntu24 vm中运行vmware-toolbox-cmd -v 检查版本 vm运行sudo apt install open-vm-tools // vm可能需要重启 vm的 /mnt 目录下如果没有 hgfs…

骨传导耳机哪个牌子好?年度五大热门骨传导耳机推荐清单来了!

近年来&#xff0c;骨传导耳机以其独特的传音方式和开放耳道的设计&#xff0c;逐渐成为运动爱好者和追求健康生活方式人群的新宠。与传统耳机相比&#xff0c;骨传导耳机不仅能够保护听力&#xff0c;还能在享受音乐的同时保持对周围环境的警觉。 随着骨传导耳机市场的不断壮…

1.MySQL的安装

目录 下载安装包 安装前环境的准备 正式安装 下载安装包 MySQL安装网址:https://www.mysql.com/cn/ 进去之后就是上面这个页面&#xff0c;进行汉化的时候将这个网页拉至最下&#xff0c;右下角点成中文就可以&#xff0c;如下这个页面。 回到页面顶端&#xff0c;点击下载&a…

并发编程---线程与进程

业务场景&#xff1a;小明去理发店理发。 小明去理发店理发&#xff0c;完成理发需要吹&#xff0c;剪&#xff0c;洗、理的过程。由这个场景我们引用进程和线程这两个 概念。 一.进程 1.什么是进程 进程是具有独立功能的程序关于某个数据集合上的一次运行活动&#xff0c;是…

基于Hadoop的NBA球员大数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

MySQL InnoDB MVCC数据结构分析

1、概述 MVCC&#xff08;Multiversion Concurrency Control&#xff09;多版本并发控制&#xff0c;通过维护不同的版本号&#xff0c;提供一种很好的并发控制技术&#xff0c;这种技术能够使读写操作不冲突&#xff0c;提升并发性能。 MySQL InnoDB存储引擎&#xff0c;在更…

Colorful/七彩虹将星X17 XS 22 Win11原厂OEM系统 带COLORFUL一键还原

安装完毕自带原厂驱动和预装软件以及一键恢复功能&#xff0c;自动重建COLORFUL RECOVERY功能&#xff0c;恢复到新机开箱状态。 【格式】&#xff1a;iso 【系统类型】&#xff1a;Windows11 原厂系统下载网址&#xff1a;http://www.bioxt.cn 注意&#xff1a;安装系统会…

设计模式、系统设计 record part02

软件设计模式&#xff1a; 1.应对重复发生的问题 2.解决方案 3.可以反复使用 1.本质是面向对象 2.优点很多 1.创建型-创建和使用分离 2.结构型-组合 3.行为型-协作 571123种模式 UML-统一建模语言-Unified Modeling Language 1.可视化&#xff0c;图形化 2.各种图&#xff08;9…

服务器操作系统【sar 命令】

sar 安装、语法参数说明以及示例 文章目录 功能概述一、功能介绍1.安装配置2. 配置3. 启动二、sar 语法及参数说明三、示例及释义1.汇报 io 传输速率信息2.内存分页信息3.块设备状态信息4.hugepages 利用率统计信息5.列长度和负载平均值6.内存利用率统计信息7.swap 交换空间利用…