skynet源码分析:运行与主要线程worker

skynet启动流程

skynet程序只有skynet-src目录,./skynet ./example/config启动
skynet_main.c读取配置文件,设置环境变量,调用skynet_start.c的skynet_start函数bootstrap

skynet_start函数初始基础服务,调用_start函数启动_timer线程、socket线程、_monitor线程以及配置的多个_worker线程开始工做api

 

skynet运行机制
skynet每一个服务最重要的是设置一个callback函数,服务向另外一个服务发消息都会压入这个服务的消息队列,等待_worker线程从全局队列取出一个服务的消息队列,而后再从这个消息队列取出一个消息使用这个服务的callback处理
游戏服务器通常会启动一个socket服务教给gate.so管理,socket服务能够接受外部msg传递到内部服务来处理。

 

monitor

 

skynet对服务的监控作得比较简陋,从设计原则上来讲,这样作也是对的,由于框架层能作的,基本就是上报和打日志,上层的业务是变化万千的,不论怎么写,均可能知足不了上层的业务需求。skynet中对服务的监控实如今skynet_monitor.c和skynet_monitor.h中,当服务可能陷入死循环的时候,就打一条日志。

 

每次消息派发,都会调用skynet_monitor_trigger,一共调两次,第一次参数source和destination是真实的值,也就是不为0。第二次调是在消息派发完成的时候,source和destination都赋0。数组

若是第一次trigger调用之后,消息派发迟迟不完成,monitor线程第一次检查,会将check_version的值赋为version。而后monitor线程第二次检查,这个时候version和check_version就会相等,并且这时候destination也不为0,就会进入释放目标服务和打印报警的流程。服务器

timer

 

skynet的timer是作游戏用得比较频繁的一个功能,分析一下它的源码仍是有意义的。并且核心的C源码除了timer和网络之外,已经基本分析得差很少了。其它都是跟lua c api相关,或者是跟lua交互比较多的。timer的源码在skynet-timer.c和skynet-timer.h中。
skynet的外部定时器是分为两部分存的,一部分存在叫near的数组里,另外一部分存在一个二维数组里,分为四个级别。

skynet中有一个timer线程,每2.5毫秒就更新一下timer中的时间。每次更新都会对一个叫time的计数器作加1操做,因此这个计数器其实能够看成时间来看待,而后对near数组中的定时器进行触发。网络

 

 

1.main函数
main函数是skynet进程的入口点,它须要一个配置文件的路径做为参数。main函数先作一些内存分配工做,而后加载配置文件里的内容。再把配置文件里的内容设置到lua环境变量_ENV。而后从_ENV里读取配置到c配置中。最后调用skynet_start。数据结构

2.skynet_start函数
skynet_start函数根据配置肯定服务是否是之后台方式启动,而后初始化timer/socket/module/mq这些数据结构,给它们分配内存,填充一些必要的字段。下一步建立和注册日志logger服务,这个logger服务是C层实现的。而后建立注册snax服务,作bootstrap操做。最后调用start函数。框架

3.start函数
这个函数会启动timer/socket/monitor/worker线程,timer/socket/monitor线程都只有一个,惟独worker线程是多个,在配置文件中以thread=num来配置的。若是配置文件中没有配,就是8个。第个worker线程都有本身的权重值,权重值越大的,给单个服务的时间片越小。socket

线程都启动完之后,就进入pthread_join,等待线程的终止。全部线程终止之后,skynet就会退出。函数



 

参考:源码分析

《skynet_summary》

《Skynet框架之菜鸟手册》

skynet源码分析(2)--消息队列mq

相关文章
相关标签/搜索