IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> web服务器升序链表定时器 -> 正文阅读

[数据结构与算法]web服务器升序链表定时器

#ifndef LST_TIMER
#define LST_TIMER

#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <stdarg.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/uio.h>
#include <time.h>

#define BUFFER_SIZE 64
class util_timer; //声明

//定义用户数据结构体
struct client_data
{
    sockaddr_in address;
    int sockfd;
    char buf[BUFFER_SIZE];
    util_timer *timer;
};

//定时器类
class util_timer
{
public:
    util_timer() : pre(nullptr), next(nullptr) {}

public:
    time_t expire;
    void (*cb_func)(client_data *);
    client_data *user_data;
    util_timer *pre;
    util_timer *next;
};

//定时器链表
class sort_timer_lst
{

private:
    util_timer *head;
    util_timer *tail;

public:
    sort_timer_lst() : head(nullptr), tail(nullptr) {}
    //链表被销毁时,删除所有定时器
    ~sort_timer_lst()
    {
        util_timer *tmp = head;
        while (tmp)
        {
            head = tmp->next;
            delete tmp;
            tmp = head;
        }
    }

    //将目标表定时器添加到链表中
    void add_timer(util_timer *timer)
    {
        if (timer == nullptr)
        {
            return;
        }
        //head头结点为空
        if (head == nullptr)
        {
            head = tail = timer;
            return;
        }
        //如果目标定时器的超时时间小于所有升序链表
        //添加到head节点
        if (timer->expire < head->expire)
        {
            timer->next = head;
            timer->pre = nullptr;
            head->pre = timer;
            head = timer;
            return;
        }
        //否则就进行添加到中间
        add_timer(timer, head);
    }

    //当某个定时事件发生变化时,调整对应的的定时器在链表中的位置
    //只考虑超时时间延长的情况,即往后面移动
    void adjust_timer(util_timer *timer)
    {
        if (timer == nullptr)
        {
            return;
        }
        util_timer *tmp = timer->next;
        //被调整的定时器在尾部
        //或者该定时器的超时值仍然小于下一个
        if (tmp == nullptr || timer->expire < tmp->expire)
        {
            return;
        }

        //如果目标定时器是头结点,则将该定时器取出,再重新插入
        if (timer == head)
        {
            head = head->next;
            head->pre = nullptr;
            timer->next = nullptr;
            //取出,重新插入
            add_timer(timer, head);
        }
        //如果不是头尾节点,在中间
        else
        {
            timer->pre->next = tmp;
            tmp->pre = timer->pre;
            add_timer(timer, timer->next);
        }
    }

    //删除目标定时器
    void del_timer(util_timer *timer)
    {
        if (timer == nullptr)
        {
            return;
        }
        //当链表中只有一个定时器时
        if (timer == head && timer == tail)
        {
            delete timer;
            head = nullptr;
            tail = nullptr;
            return;
        }

        //有多个定时器,并且定时器是链表的尾节点
        //重置尾节点
        if (timer == tail)
        {
            tail = tail->pre;
            tail->next = nullptr;
            delete timer;
            return;
        }

        //是头结点
        if (timer == head)
        {
            head = head->next;
            head->pre = nullptr;
            delete timer;
            return;
        }

        //在中间
        timer->pre->next = timer->next;
        timer->next->pre = timer->pre;
        delete timer;
    }

    //sigalrm信号每次触发就执行一次tick函数
    void tick()
    {
        if (head == nullptr)
        {
            return;
        }
        //获得当前时间
        time_t cur = time(NULL);
        util_timer *tmp = head;
        //从头结点开始依次处理每个定时器,直到遇到一个尚未到期的定时器
        while (tmp)
        {
            //当前时间小于超时时间时
            if (cur < tmp->expire)
            {
                break;
            }

            //否则调用定时器的回调函数,执行任务
            //作用是关闭套接字,从epoll中剔除
            tmp->cb_func(tmp->user_data);
            //执行完定时器中的定时任务后,就将它从链表中剔除,并重置链表头结点
            head = tmp->next;
            //判断此时头结点是否为空
            if (head)
            {
                head->pre = nullptr;
            }
            delete tmp;
            tmp = head;
        }
    }

private:
    //重载辅助函数,设为私有的
    //添加定时器到中间
    void add_timer(util_timer *timer, util_timer *lst_head)
    {
        //双指针方式
        util_timer *prev = lst_head;
        util_timer *tmp = prev->next;
        while (tmp)
        {
            if (timer->expire < tmp->expire)
            {
                prev->next = timer;
                timer->pre = prev;
                timer->next = tmp;
                tmp->pre = timer;
                break;
            }
            prev = tmp;
            tmp = tmp->next;
        }
        //遍历完都没有找到,则说明是最大的
        //将它插到尾部,并设置成tail
        if (tmp == nullptr)
        {
            prev->next = timer;
            timer->pre = prev;
            timer->next = nullptr;
            tail = timer;
        }
    }
};

#endif
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:50:47  更:2022-03-10 22:53:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:48:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码