首页 > 其他分享 >自定义定时器

自定义定时器

时间:2022-11-15 10:11:18浏览次数:55  
标签:std node 定时器 return 自定义 timer iter id

自定义定时器

#include <iostream>
#include <sys/epoll.h>
#include <chrono>
#include <functional>
#include <memory>
#include <set>
int64_t gid{0};

struct NodeBase
{
    time_t expire;//过期时间
    int64_t id;//全局唯一id
};

struct TimerNode : public NodeBase
{
    using Callback = std::function<void(const TimerNode &node)>;
    Callback cb;

    TimerNode(time_t exp, int64_t id, Callback cb)
    {
        this->expire = exp;
        this->id = id;
        this->cb = cb;
    }
};

bool operator < (const NodeBase& lhd, const NodeBase& rhd)
{
    if(lhd.expire < rhd.expire)
        return true;
    else if(lhd.expire > rhd.expire)
        return false;

    return lhd.id < rhd.id;
}
class CTimer
{
public:
    //系统启动到现在的时间
    static time_t GetTick()
    {
        auto sc = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now());
        auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(sc.time_since_epoch());
        return tmp.count();
    }

    NodeBase AddTimer(time_t msec, TimerNode::Callback cb)
    {
        time_t expire = GetTick()+msec;
        auto ele = timer.emplace(expire, GenID(), cb);
        return static_cast<NodeBase>(*ele.first);
    }

    bool DelTimer(NodeBase &node)
    {
        //C++14才能find到
        auto iter = timer.find(node);
        if(iter != timer.end())
        {
            timer.erase(iter);
            return true;
        }

        return false;
    }

    bool CheckTimer()
    {
        auto iter = timer.begin();
        if(iter != timer.end() && iter->expire <= GetTick())
        {
            iter->cb(*iter);
            timer.erase(iter);
            return true;
        }
        return false;
    }

    time_t TimeToSleep()
    {
        auto iter = timer.begin();
        if(iter == timer.end()) return -1;
        time_t diss = iter->expire - GetTick();
        return diss > 0 ? diss : 0;
    }

private:
    static int64_t GenID()
    {
        return gid++;
    }
private:
    std::set<TimerNode, std::less<>> timer;
};



int main()
{
    int epfd = epoll_create(1);
    epoll_event ev[64] = {0};
    std::unique_ptr<CTimer> timer(new CTimer());
    int i=1000;
    timer->AddTimer(1000, [&](const TimerNode &node){
        std::cout << CTimer::GetTick() << " node id:" << node.id
            << " i=" << i++ << std::endl;
    });
    timer->AddTimer(1000, [&](const TimerNode &node){
        std::cout << CTimer::GetTick() << " node id:" << node.id
            << " i=" << i++ << std::endl;
    });   
    timer->AddTimer(3000, [&](const TimerNode &node){
        std::cout << CTimer::GetTick() << " node id:" << node.id
            << " i=" << i++ << std::endl;
    });  

    auto node = timer->AddTimer(2100, [&](const TimerNode &node){
        std::cout << CTimer::GetTick() << " node id:" << node.id
            << " i=" << i++ << std::endl;
    }); 
    timer->DelTimer(node);

    while(true)
    {
        // timeout 要阻塞等待多长时间
        // -1 永久阻塞
        // 0 如果网络事件触发,立刻返回
        // >0 比如1000阻塞等待1s
        int n = epoll_wait(epfd, ev, 64, timer->TimeToSleep());
        for(int i=0; i<n; i++)
        {
            //处理网络事件
        }
        //处理定时事件
        while(timer->CheckTimer());
    }
    return 0;
}
luni@DESKTOP-Q66QS5Q:~$ g++ timer.cc -o timer -std=c++14
luni@DESKTOP-Q66QS5Q:~$ ./timer
78831834 node id:0 i=1000
78831835 node id:1 i=1001
78832934 node id:3 i=1002
78833834 node id:2 i=1003

标签:std,node,定时器,return,自定义,timer,iter,id
From: https://www.cnblogs.com/huanyinglvtuan/p/16891494.html

相关文章

  • 【AGC】远程配置如何传入自定义属性
    ​背景:现在AGC远程配置端侧服务提供的SDK支持传入自定义属性获取和更新云端配置数据了。下面将通过一个demo集成远程配置SDK来实现这一功能。 集成准备1.在AGC创建工......
  • 1710. 卡车上的最大单元数 ----- 贪心算法,自定义sort排序
    请你将一些箱子装在一辆卡车上。给你一个二维数组boxTypes,其中boxTypes[i]=[numberOfBoxesi,numberOfUnitsPerBoxi]:numberOfBoxesi是类型i的箱子的数量。numb......
  • JavaScript自定义数据类型判断函数
    functionjudgeType(ele){letres=typeofele;if(res==="object"){//短路表达式,第一个成立则返回第二个的值,第一个不成立,则返回第一个的值......
  • 自定义组件
    创建自定义组件类似于页面,一个自定义组件由jsonwxmlwxssjs4个文件组成。要编写一个自定义组件,首先需要在json文件中进行自定义组件声明(将component字段设为true......
  • 自定义页面
    [Page构造器]Page({/***页面的初始数据*/data:{},/***生命周期函数--监听页面加载*/onLoad:function(e){},/**......
  • 自定义组件传参
    参数声明Component({//参数properties:{//这里定义了innerText属性,属性值可以在组件使用时指定innerText:{type:String,value:'def......
  • 自定义组件事件
    子组件<viewbindtap="onItemChildClick"data-item="item">{{item}}</view>Component({methods:{onItemChildClick(event){this.trigger......
  • 第四十七章 开发自定义标签 - 服务器文档对象模型
    第四十七章开发自定义标签-服务器文档对象模型当CSP编译器处理CSP文档时,它首先查找与规则匹配相关的所有标记。当编译器扫描文档时,它会创建一个与CSP文档中包含的标记......
  • 基于AQS实现自定义同步类
    Mutex(互斥锁)Mutex是一个不可重入的互斥锁实现。锁资源(AQS里的state)只有两种状态:0表示未锁定,1表示锁定。下边是Mutex的核心源码:classMuteximplementsLock,java.io.......
  • Java中通过反射+自定义注解判断对象中部分属性是否为空,返回为空字段的名称或自定义含
    场景若依管理系统前后端分离版基于ElementUI和SpringBoot怎样实现Excel导入和导出:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108278834在上面进行exc......