skynet启动流程
source link: https://www.zenlife.tk/skynet_start.md
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
skynet启动流程
2014-06-12
skynet是一个框架。库的意思是,你调用它。框架的意思就是说,它调用你。所以在不搞清楚整个流程之前,会有种被编程的感觉。最近想拿skynet做点东西,所以看一看skynet的流程。
skynet example/config
参数是配置文件,配置文件中会有
- thread 线程数信息
- module_path 模块路径信息
- harbor harbor的id
- bootstrap 自举
- daemon 守护进程
系统初始化
skynet_globalinit(); skynetenvinit();
skynet_globalinit
设置了线程本地存储。skynet_env_init
创建了一个Lua虚拟机提供get和set。然后到了skynet_start
函数。在skynet_start
函数中:
skynetharborinit(config->harbor); skynethandleinit(config->harbor); skynetmqinit(); skynetmoduleinit(config->module_path); skynettimerinit(); skynetsocketinit();
每个skynet节点者有一个harbor与其它skynet节点通信。handle作用是从id或者服务名字得到`skynet_context``。mq就是初始化skynet的消息队列。
module是需要说一下的,一个符合skynet约定的so文件就是一个module,也称为一个服务。这个so文件中要包括create函数,init函数,release函数,分别要命名为模块名create/模块名init/模块名_release。skynet_module_init
函数并没有初始化具体的模块,只是初始化了模块管理自身。后面系统会调用skynet_module_instance_create
和skynet_module_instance_init
来执行具体某个模块的创建和初始化。
timer和socket都是肯定要用到的非常基础的组件,在这里进行初始化了。
bootstrap(config->bootstrap);
在这个函数中启动了第一个skynet_context,默认情况下是执行snlua bootstrap。
在这里兜一圈,会最终运行到脚本bootstrap.lua中去。而bootstrap.lua最终会调用到config中指定的start脚本,在默认的例子中也就是example/main.lua。
如果想自己定义系统的启动行为,就通过配置config->bootstrap。
_start(config->thread);
在这个函数中会创建三条线程分别运行monitor,timer,socket。然后根据config中配置的线程数,创建线程并运行worker函数。
线程池+消息队列
然后就进入了传统的线程池+消息队列的循环中。每个worker会不停地取一条消息,查找这条消息是发给哪个skynet_context
的,然后调用这个skynet_context
相应的callback处理这条消息。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK