游戏服务器架构:基于匿名函数的高性能异步定时器系统

news2024/11/15 12:48:58

作者:码客(ygluu 卢益贵) 关键词:游戏服务器架构、匿名函数、高性能、异步定时器。

一、前言

本文主要介绍适用于MMO/RPG游戏服务端的、基于匿名函数做定时器回调函数的、高性能异步触发的定时器系统的设计方案,以解决常规线程loop-run-check模式的弊端。本文使用伪代码简明阐述理论。

二、系统框图

如图所示,本方案四大亮点

1、Main-Thread一直Wait-Msg(堵塞模式),抛弃了常规的线程loop-run-check模式,避免了无意义的Run、Sleep、业务Obj众多时的桶轮询机制,最大的发挥线程性能。

2、Timer-Thread仅根据interval来检查和触发,同一个interval的多个定时器只触发一次事件入列(第④步)。这样当定时器数量达到百万级的时候,第④步产生的消息队列数量非常少(因为游戏场景下的interval数值范围是有限的),减少了高频触发导致的线程锁和线程唤醒的性能消耗。

3、兼顾成员函数指针和匿名函数形式的定时器回调函数,开发更加简单便捷。

4、在异步线程触发消息的情况下,能保证定时器回调的安全性(定时器宿主Obj和关联上下文数据的安全性)。

三、时间轮设计(间隔时间)

时间精度:accuracy = 50 (单位毫秒,自定义常量)

预期间隔时间:interval

实际间隔时间(accuracy倍数): interval = interval / accuracy + accuracy * int( interval % accuracy > 0)

四、业务obj对象设计

class obj
{
    obj()
    {
        m_timer = new timer(mgr);
        // 成员方法指针方式触发定时器
        m_timer->open(start_time, interval, trigger_count, on_timer);  // 第①步
        // 匿名函数方式触发定时器
        m_timer->open(start_time, interval, trigger_count,    // 第①步
             []()
             {
              });
    };

    ~obj()
    {
        delete m_timer;
    };

    void on_timer()
    {
    };
};

五、定时器类设计

class timer
{
    timer(mgr)
    {
        m_mgr = mgr;
    };

    ~timer()
    {
        clear();
    };

    uint64 open(start_time, interval, trigger_count, std:function<void(void)> callback)
    {
        auto id = m_mgr(this, start_time, interval, trigger_count, callback);  // 第②步
        m_timer_ids.add(id);
        return id;
    };

    void clear()
    {
        for (auto id : m_timer_ids)
        {
            m_mgr->close(id);
        }
        m_timer_ids.clear();
    };

    close(id)
    {
        m_timer_ids.del(id);
        m_mgr->close(id);
    };
};
 

六、管理器类设计

class timer_mgr
{
    uint64 open(timer, start_time, interval, trigger_count, callback)
    {
        auto id = ++id_count;
        interval = interval / accuracy + accuracy * int( interval % accuracy > 0)

        auto info = {id, timer, create_time, last_time, start_time, interval, trigger_count, callback};
        // 根据触发间隔时间来分类管理定时器(回调函数)
        auto infos = infos_by_interval.find(interval);
        infos.add(id, info);

        // 告诉定时器线程增加触发间隔时间
        timer_thread->add(interval); // 第③步

        return id;
    };

    close(id)
    {
        auto info = info_by_id.find(id);
        auto infos = infos_by_interval.find(info->interval);
        infos.del(id);
        info_by_id.del(id);
    };

    // 第⑤步
    trigger(interval)
    {
        auto infos = infos_by_interval.find(interval);
        for (auto info: infos)
        {
            // 检查是否有延时启动时间
            if (info->start_time)
            {
               if (get_tick_count()- info->create_time < info->create_time)
               {
                   continue;
                }
                // 下次不再进入本分支
                info->start_time = 0;
            }            

            // call定时器回调函数 第⑥步
            info->callback();
 
            // 检查定时器寿命
            info->trigger_count++;
            if (info->trigger_count == 0)
            {
               info->m_timer->m_timer_ids->del(id);
               infos .del(id);
            }
        }

        // 告诉定时器线程删除触发间隔时间
        if (infos->size() == 0)
        {
             timer_thread->del(interval);  // 第步
        }
    };
};
 

七、定时器线程类设计

class timer_thread
{
    void add(interval)
    {
        lock();
        if (!m_intervals.find(interval)) 
        {
            m_intervals.add(m_intervals, {interval, get_tick_count()});
        }
        unlock();
    }

    void del(interval)
    {
        lock();
        m_intervals.del(m_intervals);
        unlock();
    }

    void check()
    {
        auto now = get_tick_count();
        for (auto info: m_intervals)
        {
             if (now - info->last_time) >= info->interval)
             {
                  info->interval = now;
                  m_main_queue.push(info->interval);  // 第④步
             }
        }
    }

    // 线程启动省略
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《深入浅出WPF》读书笔记.7依赖属性和附加属性

《深入浅出WPF》读书笔记.7依赖属性和附加属性 背景 总结一下wpf依赖属性和附加属性的底层逻辑&#xff0c;方便更好的理解使用。 属性 CLR属性由来 static属性和非static属性的区别 static属性:对类有意义&#xff0c;内存只有一个实例&#xff1b; 非static属性:对类实…

WPF—LiveCharts图表

LiveCharts图表 LiveCharts是一个简单灵活、交互式以及功能强大的跨平台图表库&#xff0c;支持wpf、winform...应用程序。 快速入门 安装 在应用程序中右键引用​&#xff0c;点击管理NuGet程序包​&#xff0c;选择浏览​&#xff0c;搜索LiveChartsCore.SkiaSharpView.W…

自动驾驶-机器人-slam-定位面经和面试知识系列10之高频面试题(04)

这个博客系列会分为C STL-面经、常考公式推导和SLAM面经面试题等三个系列进行更新&#xff0c;基本涵盖了自己秋招历程被问过的面试内容&#xff08;除了实习和学校项目相关的具体细节&#xff09;。在知乎和牛客也会同步更新&#xff0c;全网同号&#xff08;lonely-stone或者…

Cortex-A7的GIC(通用中断控制器):专有名词简介

0 资料 ARM Generic Interrupt Controller Architecture version 2.0 Architecture Specification1 专有名词简介 1.1 中断状态 说明&#xff1a; Inactive&#xff1a;未激活&#xff0c;中断无效。中断非挂起或非激活。 Pending&#xff1a;挂起&#xff0c;中断有效。等待…

【Web】NepCTF 2024题解

目录 PHP_MASTER!! NepDouble 蹦蹦炸弹&#xff08;boom_it&#xff09; NepRouter-白给 Always RCE First PHP_MASTER!! PHP反序列化键值逃逸mb_strpos与mb_substr连用导致的字符注入 https://www.cnblogs.com/EddieMurphy-blogs/p/18310518 flag在phpinfo里 payloa…

1/f噪声影响及解决措施

在将6位半数字万用表输入短接时&#xff0c;观察其输出。在逐渐增加均值次数后&#xff0c;噪声开始下降&#xff0c;达到一定程度后便停止下降&#xff0c;随着时间的推移&#xff0c;停止下降的噪声在逐渐增加&#xff0c;该部分主要是1/f噪声影响。 这种1/f噪声&#xff08;…

mPLUG-Owl3环境搭建推理测试

mPLUG-Owl3环境搭建&推理测试 引子 多模态的大模型也写了很多篇&#xff0c;阿里系的之前有一篇Qwen-VL的相关部署&#xff0c;感兴趣的童鞋请移步&#xff08;Qwen-VL环境搭建&推理测试-CSDN博客&#xff09;。今天这个mPLUG-Qwl3&#xff0c;更新换代也很快&#x…

Windows下线程的竞争与资源保护(win32-API)

一、前言 在线程编程中&#xff0c;资源共享与保护是一个核心议题&#xff0c;尤其当多个线程试图同时访问同一份资源时&#xff0c;如果不采取适当的措施&#xff0c;就会引发一系列的问题&#xff0c;如数据不一致、竞态条件、死锁等。为了确保数据的一致性和线程安全&#…

【游戏速递】 小猪冲刺:萌动指尖的极速挑战,小虎鲸Scratch资源站独家献映!

在线玩&#xff1a;Scratch小猪冲刺&#xff1a;全新挑战的几何冒险游戏-小虎鲸Scratch资源站 想象一下&#xff0c;一群憨态可掬的小猪&#xff0c;穿上炫酷的装备&#xff0c;踏上了追逐梦想的赛道。它们或跳跃、或滑行&#xff0c;灵活躲避各种障碍&#xff0c;只为那终点的…

微软亚研院哈佛:同行评议互一致的rStar

本来想将近期另一篇DeepSeek的“DeepSeek-Prover-V1.5: Harnessing Proof Assistant Feedback for Reinforcement Learning and Monte-Carlo Tree Search”与这篇同样基于强化学习思想的小型清爽型推理模型放在一个笔记中相互对比借鉴一下&#xff0c;考虑虽然两者有着一些共通…

论文3解析(复现):六自由度机械臂轨迹规划研究+机器人基础知识-部分1

论文&#xff1a;六自由度机械臂轨迹规划研究&#xff0c;马强 机器人一些关于数学基础的知识&#xff0c;简单的说一下&#xff1a; 向量 在机器人中&#xff0c;向量的含义并不是算算数那样子&#xff0c;而是在空间的本质含义。 向量叉乘&#xff1a;ab |a|*|b|*sin&am…

燃烧控制模型

加热炉燃烧控制 主要功能&#xff1a; 1&#xff0e; 把要轧制的钢坯加热的规定温度&#xff0c;即出炉目标温度&#xff0c;并尽量减少黑印。 2&#xff0e; 协调加热炉及轧机的生产能力&#xff0c;以提高轧机总的生产效率。 3&#xff0e; 节省燃料 在轧钢生产过程中&#x…

s3c2440移植Linux内核之引导

最近想尝试把新的Linux内核移植到tq2440的开发板上&#xff0c;看看还能不能顺利的跑起来。我的基础版本是买板子的时候提供的2.6.30版本&#xff0c;编译器版本是4.3.3.。 下载源码和编译器 下载linux源码&#xff0c;源码的官方网站是The Linux Kernel Archives&#xff0c…

沉积层的厚度为自振周期波长的1/4

要理解为什么是1/4&#xff0c;需要明白如下两点。 &#xff08;1&#xff09;自振周期&#xff08;fundamental model, or first harmonic&#xff09;取决于在某边界条件下可以出现驻波&#xff08;standing wave&#xff09;的最短距离。Standing wave, also known as a st…

AI助力水体保护区无人值守垂钓智能预警,基于YOLOv8全系列【n/s/m/l/x】参数模型开发构建水体保护区场景下无人值守垂钓智能检测预警系统

保护我们赖以生存的自然生态环境&#xff0c;无疑是一项意义深远且需要长期坚持的任务。自然界的生态系统&#xff0c;由水、气、森林、土壤等多要素组成&#xff0c;它们相互依存、相互影响&#xff0c;共同维系着地球的生态平衡。然而&#xff0c;在人类活动的影响下&#xf…

浅谈进程,线程,协程以及服务端高并发的处理

进程、线程、协程 进程&#xff1a;独立的程序实例&#xff0c;资源开销较大&#xff0c;适合隔离性要求高的任务。 独立性&#xff1a;进程具有独立的内存空间和资源&#xff0c;互不干扰。 资源开销大&#xff1a;由于每个进程都需要分配独立的内存和资源&#xff0c;创建和…

5个常用的物理仿真JavaScript插件

还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0c;webgl&#xff0c;ech…

【Python学习手册(第四版)】学习笔记21-模块概览

个人总结难免疏漏&#xff0c;请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。 import操作和模块是Python之中程序架构的核心。本文主要介绍了模块、属性以及导入的基础知识&#xff0c;并探索了import语句的操作&#xff08;搜索、可选编译、…

不同搜索引擎蜘蛛的功能、‌抓取策略与技术实现差异探究

搜索引擎作为互联网信息检索的重要工具&#xff0c;‌其核心功能依赖于背后的“蜘蛛”程序。‌这些蜘蛛程序负责访问互联网上的各种内容&#xff0c;‌并建立索引数据库&#xff0c;‌以便用户能够快速准确地找到所需信息。‌然而&#xff0c;‌不同搜索引擎的蜘蛛在功能、‌抓…

Python爬取静态网页技术解析

内容导读 实现HTTP请求解析网页存储数据静态网页爬取实例 一、实现HTTP请求 1、爬虫场景简介 &#xff08;1&#xff09;基本功能 爬虫的基本功能是读取URL和爬取网页内容&#xff0c;这就需要爬虫具备能够实现HTTP请求的功能。请求过程主要包括生成HTTP请求、请求头处理、…