Skynet学习
skynet启动流程
skynet启动的main方法,是在skynet_mian.c文件中,具体实现为
int main(int argc,char* argv[]) {
const char* config_file = NULL;
if (argc > 1) {
config_file = argv[1]; //取得配置文件名
}else{
fprintf(stderr, "Need a config file. Please read skynet wiki : https://github.com/cloudwu/skynet/wiki/Config\n"
"usage: skynet configfilename\n");
return 1;
}
skynet_globalinit(); //全局初始化
skynet_env_init(); //环境初始化
sigign(); //SIGPIPE 信号处理
struct skynet_config config;
struct lua_State * L = luaL_newstate();
luaL_openlibs(L); //link lua lib
int err = lua_loadbufferx(L,load_config,strlen(load_config), "=[skynet config]","t");
assert(err == LUA_OK);
lua_pushstring(L,config_file);
err = lua_pcall(L,1,1,0);
if (err) {
fprintf(stderr,"%s\n",lua_tostring(L,-1));
lua_close(L);
return 1;
}
_init_env(L);
//从环境读取配置存入skynet_config数据结构中
config.thread = optint("thread",8); //工作线程数
config.module_path = optstring("cpath","./cservice/?.so"); //模块地址:用C编写的服务模块的位置
config.harbor = optint("harbor", 1); //节点编号,为零代表单节点模式
config.bootstrap = optstring("bootstrap","snlua bootstrap");// skynet 启动的第一个lua服务以及其启动参数
config.daemon = optstring("daemon", NULL);//配置是否以守护进程启动
config.logger = optstring("logger", NULL);//配置 skynet_error 输出到什么地方
config.logservice = optstring("logservice", "logger");
config.profile = optboolean("profile", 1);
lua_close(L);//关闭虚拟机
skynet_start(&config);//启动
skynet_globalexit();//全局退出
return 0;
}
这里主要读取解析配置文件,接下来主要的流程是从 skynet_start(&config)进入,skynet_start()具体如下
void skynet_start(struct skynet_config* config) {
struct sigaction sa;
sa.sa_handler = &handle_hup;
sa.sa_flags = SA_RESTART;
sigfillset(&sa.sa_mask);
sigaction(SIGHUP,&sa,NULL);
if(config->daemon){
//以守护进程启动
if (daemon_init(config->daemon)) {
exit(1);
}
}
//初始化各个组件
skynet_harbor_init(config->harbor);//harbor初始化
skynet_handle_init(config->harbor);//句柄初始化
skynet_mq_init();//消息队列初始化
skynet_module_init(config->module_path);//模块初始化
skynet_timer_init();//时钟初始化
skynet_socket_init