• 游戏系统线程和线程池的重要性


         我们知道毫无节制地申请内存和释放内存,必定会导致系统内存碎片剧烈地增加,最直接导致的后果是系统内存资源枯竭,游戏状态越来越慢,各种反应不及时,各种未知错误层出不穷!

        直到现在,我发现游戏变慢,很多人都归结为客户端的问题,其实啊,更多的问题出在服务端上面。当然还有一部分原因在于逻辑的不合理。客户端和服务端是通过消息机制进行通讯的。说白了,就是通过各种命令运行游戏的。

        如果逻辑设置不合理就会因为讯息的延迟而形成申请的资源无法释放而导致内存泄漏和各种系统参数错误。

        可见,服务端的不稳定就会出现诸多未知的问题,为什么是未知的,因为很多问题不一定好查,并不是所有错误都是重复的。

        大家可以看见原来的代码是多么疯狂,随便申请内存,随便释放内存,上一刻申请内存,下一刻就删除释放。尤其是通讯模块,加载模块,几乎是毫无节制地开销系统资源。可以想象一下,仅仅是那么一两秒钟,到底开销了多少资源?

        测试之中,我最烦的就是各种错误。

        于是,我这段时间都是捋这些代码。目前效率还可以。添加了线程池模式,系统稳定很多。

        什么是线程池,嗯,是的,我们搜资料,得看一通废话之后,再各种理解各种哲学思想啥的,然后才稍微懂了一点。

        废话就是废话,再高级的废话无非是高级的废话而已。

        两条TList链表,一条专门记录加载的内存块,命名为忙碌。

        一条命名为空闲。

        操作很简单,负责申请内存块的那条链表,就是忙碌那条链表,将申请的内存使用指针记录,然后添加。

        那么删除呢,不是直接释放内存,而是把需要删除的指针赋给空闲的那条链表,由它来负责记录。之后才删除本记录。记得不要释放内存块,否则,笑话就大了。

         那么下一次申请内存块的时候,我们先问一下空闲链表有没有“饭”可以吃,就是说,空闲链表的数量是否大于零。如果有值的,那么就从空闲链表这里取内存块。不用向系统伸手了!当然空闲链表得把这条已经给出去的记录在本链表体内删除,否则一个天大的笑话就会产生!

         其实就是简单的交换指针,内存块重复使用!

         但是,有一点需要记住,数据结构大小必须是固定而统一的,否则,记录内存块没有任何意义,因为你得每次检测数据的大小,然后再重新分配内存。这样的方式是错误的,因为重新分配内存同样导致内存碎片增加,达不到我们想要的效果。

          另外禁止在数据结构简单使用String类型,因为它没有数据的时候,就是个专门捣乱的家伙,因为它什么屁都不是。这个玩意给我带来的麻烦最多。大家应该看到代码里面大量的String了吧,是方便,但是在Delphi 10.1里面,它不是个友善的家伙。等你们升级到了这个版本之后,就真真正正明白了。

          所以数据结构带有字符串的,一律采用定长机制,就是这种:String[...],要不然后果严重!

          什么屁线程池,就用上面这种就好。

         这种方式是最初学完成端口IOCP的时候才了解的,呵呵,真心有意思。简单意味着高效!当然还是需要封装一番,要不然一样给你带来麻烦。

         另外声明一下,我的所有开发都是在Delphi XE2以上的版本,目前是Delphi 10.1

         我了解了一下,不少人不喜欢采用API来制作自己的多线程模块,有些人说,我们得相信那些工程师,不必再另造轮子了。嘿嘿,开发本身就是一个重复造轮子的过程,你以为你开发的玩意,写的代码没有人做过,切,不知所谓了。

        服务器编程,说白了,能用最简单的方式做,就一定不要采用类继承,很多资源不是你需要的,也不需要这些玩意。如果你明白有些时候,BUG的产生是父类资源没有得到有效的释放导致的,那么我们一定需要相信那些工程师了,对吧?这是个笑话!

        只有你自己在一定范围可以控制的,才是好的东西!

       API下开发,其实不是让你做得多么完美,而是我们要做具有针对性的模块。

       你可以采用几种方式开发多线程模块,针对不同的环境来做特定的运行机制。

       因为简单所以高效,就是这个结果!那些你不需要的玩意通通扔掉!

       我就采用了事件方式来针对游戏中心程序进行改善。事件方式有三种功能,运行一次、一直运行、暂停模式。按照不同的情况自由触发线程运行,嗯,是不是挺有意思的。

       当然里面我采用了完成端口一些方式,比如类指针传递,工作线程函数,线程池等。全部API构建,代码流程简单,没有那些多层继承玩意。

      我最憎恶那些多重继承的玩意,上一个漏洞继承到下一个下下一个去,天知道这些玩意有个鸟用。文件是一堆堆的,烦!

      具体的创建过程不需要了,因为不复杂,真的,真的不复杂,甚至比你继承那些玩意还简单,因为你很容易了解所需要的函数以及功能,随手就可以封装一个出来用。如果你觉得烦,就到万一的博客去取经,很清楚明白!网上其它地方哆嗦一大推,各种哲学,免了!

  • 相关阅读:
    github登录不上?!
    js -- even-loop 理解
    前端面试积累(整理中)
    各个ctr算法的比较
    常用ctr算法比较
    BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
    Attention is All You Need
    理解word2vec
    EDA时的画图函数
    alphogo 理解
  • 原文地址:https://www.cnblogs.com/GameDelphi/p/7985082.html
Copyright © 2020-2023  润新知