────────────────────────────────────────────────────────────────
┌————————————┐
│▉▉♥♥♥♥♥♥♥♥ 99% │ ♥❤ 鱼沈雁杳天涯路,始信人间别离苦。
└————————————┘
对你的感情正在充电中,请稍侯…
────────────────────────────────────────────────────────────────

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

────────────────────────────────────────────────────────────────

  • 掌握框架是怎么解决问题的。
  • 掌握框架的核心技术。
  • 掌握框架的开发思路。
    目的是基于框架的做正确的事情,actor并发模型。
    在这里插入图片描述
    在这里插入图片描述
    多进程用socket通信,而不是采用管道,信号。因为socket不会局限这个进程部署在哪个位置。前人总结的经验,前四者属于并发实体,不建议使用共享内存。
  • 不要通过共享内存而通信,而应该用通信来共享内存。

skynet

skynet属于多核并发模型,轻量级游戏服务器框架,基于c和lua开发的。
先看skynet的配置文件,game.conf。

  • 其中的start=‘main”。通常一台机器只会启动一个skynet,因为是skynet独占cpu,这样cpu都能满负荷的被使用。在一个内核当中启动多个我们用户自己实现的进程。main相当于是一个初始化的过程,开始启动这个程序。
  • logger=nil表示日志输出的位置为控制台。
  • lua_cpath:
  • c.path:
    在这里插入图片描述
  • newservice就是一个服务,也是一个抽象的进程,由内核调度,切非常吃资源。根据agent找到agent.lua,再去创建一个服务。
    进程有一个有一个非常好的优点,就是资源隔离,每一个进程就是一个资源活体。
    在这里插入图片描述
  • instance:隔离的运行和环境,
  • mode 哪一个是启动文件看。
  • cb:运营进程对应的函数。
  • queue:消息队列。
    在这里插入图片描述
    网络的消息一定会到达一个服务去处理,将网络消息包装成一个消息放入消息队列,然后将消息队列中取出消息然后作为回调函数作为参数,最后在隔离环境去运行actor。
  • 处理网络数据:skynet采用reactor网络模型处理网路数据,对io的处理转换为对事件的处理
  • actor之间的消息传递:并不难,只是一个指针之间的移动。
  • 定时消息

actor的调度问题

actor的调度是由线程池的驱动调用的。
在这里插入图片描述
值得注意的是,关注点在线程池作为消费者,队列数据中从无到有如何唤醒线程池,从有到无如何让线程池休眠。
在这里插入图片描述

redis是如何调度线程池的?

主线程主动获取io线程互斥锁,io线程只能挂起了,线程就会休眠。

再来一起看skynet的线程池?

在这里插入图片描述
根据cpu的数量创建work thread pool,线程池驱动actor运行,本身也是一个生产者。

自旋锁和互斥锁的区别

这真是一个老生常谈的话题。
在这里插入图片描述
memchd,nginx都是加的自旋锁,为了充分利用多核,我们尽量不要让出执行权。
在这里插入图片描述

  • 代码所示,当消息队列的消息为空时,通过条件变量让线程池休眠。
  • 有消息来的时候要调用notify,当线程池要退出时要broadcast。
  • 网络线程和定时器线程需要wakeup长生消息时要唤醒,而actor之间传递消息则不用。因为actor之间传递不会导致线程池为空,更不会休眠,所以不必wakeup。
  • actor应该如何调度?全局消息队列时actor消息队列的一个引用。

在这里插入图片描述
错位执行,优化skynet,如果权重一致出现消息堆积。
在这里插入图片描述

  • 值得注意的是:用携程消除回调这个方法似乎有增多的这个趋势。没有数据让出携程,当数据来到用携程处理,而我们用这种方法,原先异步处理转换为同步的。reactor是异步事件,而这样一番翻云覆雨之后变成了同步非阻塞。
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐