C++服务器开发之定时器设计方案

简介: 定时器应⽤:1.⼼跳检测 2.技能冷却 3.武器冷却 4.倒计时 5.其它需要使⽤超时机制的功能

定时器应⽤

  • ⼼跳检测
  • 技能冷却
  • 武器冷却
  • 倒计时
  • 其它需要使⽤超时机制的功能

适合定时器的数据结构有红黑树,最小堆,跳表,时间轮,其中最小堆实现的定时器最常见

最小堆的堆顶永远是最小的,超时检测时只需要从堆顶开始检测就行

时间获取与定时函数

由于是跨平台,所以不使用操作系统所提供的,

linux下可以使用timerfd,timerfd被抽象成fd文件,配合epoll_wait的timeout参数可以使心跳线程和工作线程处于同一线程,避免伪心跳包出现

c++提供三种获取时间的类

  1. std::chrono::system_clock
  2. std::chrono::steady_clock
  3. std::chrono::high_resolution_clock

由于system_clock是获取系统时间,如果系统时间被更改,或者网络校时,都会使时间被更改,所以不适合使用,steady_clock是只会自增(例如开机时间),high_resolution_clock在不同的系统中可能有不同的实现(通常它只是 std::chrono::steady_clock或 std::chrono::system_clock的别名),所以我们选择std::chrono::steady_clock

而定时则选取std::condition_variable::wait_until函数

定时器接口

最小堆实现

对于每一个任务都要有以下几个基本字段描述

  • 超时后调用的回调函数
  • 超时的时长
  • 以及一个该任务是否一直执行的标志

对于每一个定时器有几个基本方法描述

  • 初始化一个定时器
  • 添加任务
  • 执行到期任务

c++对象封装后的代码

timer.h
#pragma once
#include <functional>
#include <chrono>
#include <queue>
#include <mutex>
#include <condition_variable>

using timedTesk = std::function<void()>;
using timeDuration = std::chrono::milliseconds;
using timePoint = std::chrono::time_point<std::chrono::steady_clock>;

class timerNode {
   
public:
    bool operator < (const timerNode& obj) const {
    return point > obj.getPoint(); }

    timePoint getPoint() const {
    return point; }

    timerNode(int milliseconds, timedTesk fun, bool keep);
    timerNode(const timerNode& obj);

    void operator()() const {
    tesk(); }
    bool is_keep() const {
    return keep; }

    //刷新超时时间点
    void flush();
private:
    timedTesk       tesk;//定时任务
    bool            keep;//是否保活
    timeDuration    time;//超时时长
    timePoint       point;//执行的时间点
};

class timer
{
   
public:
    //添加任务
    void addTimer(int time, timedTesk tesk, bool keep);

    //执行定时器
    void start();

    //销毁定时器
    void destroy();

private:

    //执行到期任务:expire_timer
    void expire_timer();

private:
    //存放定时任务的小根堆
    std::priority_queue<timerNode, std::vector<timerNode>, std::less<timerNode>> queue;

    //保证小根堆线程安全
    std::mutex que_mtx;

    //定时器销毁标志
    bool is_destroy;

    //定时std::condition_variable::wait_until
    std::mutex mtx;
    std::condition_variable cv;
};
timer.cpp
#include "timer.h"
#include <climits>
#include <thread>

timerNode::timerNode(int milliseconds, timedTesk fun, bool keep)
    :time(milliseconds), tesk(fun), keep(keep)
{
   
    flush();
}

timerNode::timerNode(const timerNode& obj) :time(obj.time), tesk(obj.tesk), keep(obj.keep)
{
   
    flush();
}

void timerNode::flush()
{
   
    point = std::chrono::steady_clock::now() + time;
}

void timer::addTimer(int time, timedTesk tesk, bool keep)
{
   
    std::lock_guard<std::mutex> lock(que_mtx);
    queue.emplace(time, tesk, keep);
    cv.notify_one();
}

void timer::start()
{
   
    is_destroy = false;
    std::thread th(&timer::expire_timer, this);
    th.detach();
}

void timer::destroy()
{
   
    is_destroy = true;
}

void timer::expire_timer()
{
   
    while (!is_destroy)
    {
   
        std::unique_lock<std::mutex> lock(mtx);
        //获取堆顶时间,没有则wait一个最大时间
        auto time = queue.empty() ? std::chrono::steady_clock::now() + std::chrono::hours(INT_MAX) : queue.top().getPoint();
        if (cv.wait_until(lock, time) == std::cv_status::no_timeout) {
   //有新的定时任务加入
            //新任务中可能存在比之前超时时间更小的任务,通过continue刷新超时时间
            continue;
        }
        else {
   
            //处理超时任务
            while (!queue.empty() && queue.top().getPoint() < std::chrono::steady_clock::now())
            {
   
                timerNode node = queue.top();
                {
   
                    std::lock_guard<std::mutex> lock_(que_mtx);
                    queue.pop();
                    /*
                    如果tesk设置了keep为true,但是直接修改超时的时间点的话tesk对象在小根堆中的位置不会改变,所以只能通过先pop在push的方式更新tesk节点在小根堆中的位置
                    */
                    if (node.is_keep())
                        queue.emplace(node);
                }
                node();//执行tesk运算符重载函数
            }
        }
    }
}
目录
相关文章
|
1月前
|
安全 网络安全 定位技术
网络通讯技术:HTTP POST协议用于发送本地压缩数据到服务器的方案。
总的来说,无论你是一名网络开发者,还是普通的IT工作人员,理解并掌握POST方法的运用是非常有价值的。它就像一艘快速,稳定,安全的大船,始终为我们在网络海洋中的冒险提供了可靠的支持。
78 22
|
3月前
|
弹性计算 负载均衡 Java
【上云基础系列 02-01】通过SLB+1台ECS+ESS弹性伸缩,搭建一个精简版的上云标准弹性架构(含方案及教程)
通常,构建一个弹性架构(即使是一个最基础的入门版),至少需要2台ECS。但是,很多小微企业刚开始上云的时候,为了节省成本不愿意购买更多的服务器。通过 “ALB+ESS弹性伸缩+1台ECS+RDS”方案,在保障低成本的同时,也不牺牲业务架构的弹性设计,更避免了很多人因为节省成本选择了单体架构后频繁改造架构的困局。 方案中的几个设计非常值得小微企业借鉴:(1)通过ALB/RDS的按量付费,节省了初期流量不大时的费用;(2)通过ESS弹性伸缩,不需要提前购买服务器资源,但是当业务增长或减少时却保持了资源弹性自动扩缩容。
|
3月前
|
存储 人工智能 并行计算
2025年阿里云弹性裸金属服务器架构解析与资源配置方案
🚀 核心特性与技术创新:提供100%物理机性能输出,支持NVIDIA A100/V100 GPU直通,无虚拟化层损耗。网络与存储优化,400万PPS吞吐量,ESSD云盘IOPS达100万,RDMA延迟<5μs。全球部署覆盖华北、华东、华南及海外节点,支持跨地域负载均衡。典型应用场景包括AI训练、科学计算等,支持分布式训练和并行计算框架。弹性裸金属服务器+OSS存储+高速网络综合部署,满足高性能计算需求。
|
5月前
|
存储 弹性计算 运维
端到端的ECS可观测性方案,助力云上业务安全稳定
本文介绍了云原生时代保障业务系统可靠性的方法和挑战,重点探讨了阿里云ECS在提升业务稳定性、性能监控及自动化恢复方面的能力。文章分为以下几个部分:首先,阐述了业务可靠性的三个阶段(事前预防、事中处理、事后跟进);其次,分析了云上业务系统面临的困难与挑战,并提出了通过更实时的监测和自动化工具有效规避风险;接着,详细描述了ECS实例稳定性和性能问题的解决方案;然后,介绍了即将发布的ECS Lens产品,它将全面提升云上业务的洞察能力和异常感知能力;最后,通过具体案例展示了如何利用OS自动重启和公网带宽自适应调节等功能确保业务连续性。总结部分强调了ECS致力于增强性能和稳定性的目标。
|
6月前
|
NoSQL 容灾 MongoDB
MongoDB主备副本集方案:两台服务器使用非对称部署的方式实现高可用与容灾备份
在资源受限的情况下,为了实现MongoDB的高可用性,本文探讨了两种在两台服务器上部署MongoDB的方案。方案一是通过主备身份轮换,即一台服务器作为主节点,另一台同时部署备节点和仲裁节点;方案二是利用`priority`设置实现自动主备切换。两者相比,方案二自动化程度更高,适合追求快速故障恢复的场景,而方案一则提供了更多的手动控制选项。文章最后对比了这两种方案与标准三节点副本集的优缺点,指出三节点方案在高可用性和数据一致性方面表现更佳。
479 5
|
6月前
|
存储 Unix Linux
服务器数据恢复—DELL EqualLogic PS6100系列存储简介及发生故障后的处理方案
DELL EqualLogic PS6100系列存储采用虚拟ISCSI SAN阵列,支持VMware、Solaris、Linux、Mac、HP-UX、AIX操作系统,提供全套企业级数据保护和管理功能,具有可扩展性和容错功能。
|
7月前
|
Linux C语言 C++
vsCode远程执行c和c++代码并操控linux服务器完整教程
这篇文章提供了一个完整的教程,介绍如何在Visual Studio Code中配置和使用插件来远程执行C和C++代码,并操控Linux服务器,包括安装VSCode、安装插件、配置插件、配置编译工具、升级glibc和编写代码进行调试的步骤。
941 0
vsCode远程执行c和c++代码并操控linux服务器完整教程
|
8月前
|
存储 运维 监控
服务器高效运维管理方案
智能运维作为保障业务连续性和提升系统性能的关键环节,其重要性日益凸显。服务器作为承载各类应用与数据的核心基础设施,其稳定性、安全性和性能直接关系到企业的业务运行效率和用户体验
333 1
|
8月前
|
存储 弹性计算 SDN
企业级 ECS 集群的构建需要综合考虑多个因素,通过不断的比较和对比不同的方案,选择最适合企业自身需求和发展的架构。
【9月更文挑战第5天】在数字化商业环境中,构建企业级ECS(弹性计算服务)集群对提升业务稳定性、扩展性和性能至关重要。本文将比较传统物理服务器与ECS架构,分析云服务商选择(如AWS和阿里云)、实例配置(CPU/内存)、网络架构(SDN vs 传统)及存储方案(本地存储 vs 云存储),帮助企业根据自身需求选出最优方案,实现高效稳定的ECS集群部署。
151 18
|
9月前
|
弹性计算 运维 搜索推荐
阿里云建站方案参考:云服务器、速成美站、企业官网区别及选择参考
随着数字化转型的浪潮不断推进,越来越多的企业和公司开始将业务迁移到云端,而搭建一个专业、高效的企业官网成为了上云的第一步。企业官网不仅是展示公司形象、产品和服务的重要窗口,更是与客户沟通、传递价值的关键渠道。随着阿里云服务器和建站产品的知名度越来越高,越来越多的用户选择阿里云的产品来搭建自己的官网。本文将深入探讨在阿里云平台上,如何选择最适合自己的建站方案:云服务器建站、云·速成美站还是云·企业官网。
379 13
阿里云建站方案参考:云服务器、速成美站、企业官网区别及选择参考

热门文章

最新文章