Linux服务器开发,Skynet设计原理
鱼沈雁杳天涯路,始信人间别离苦推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习掌握框架是怎么解决问题的。掌握框架的核心技术。掌握框架的开发思路。目的是基于框架的做正确的事情,actor并发模
────────────────────────────────────────────────────────────────
┌————————————┐
│▉▉♥♥♥♥♥♥♥♥ 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是异步事件,而这样一番翻云覆雨之后变成了同步非阻塞。
更多推荐
所有评论(0)