前言
- 这是一遍关于
skynet源码分析的blog,中间会对lua源码做对比
正文
skynet执行的入口文件是skynet_main.c,先来看看int main执行了些什么。config_file是启动skynet执行的配置文件,首先会new一个lua vm,加载一下标准库,luaL_loadbufferx(L, load_config, strlen(load_config), "=[skynet config]", "t")是编译了load_config(lua会把代码文件看作成一个chunk,并push进栈里,也就是Lclouse,lua_pcall会根据push的clouse的类型,分别去执行(因为区分c和luaclouse)。这些的作用就是把配置文件解析出来,通过lua的全局表取出配置参数。
所有
lua服务都是通过sn创建的服务skynet_main.c文件中main函数源码注释
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54int
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();
struct skynet_config config;
// init the lock of code cache
luaL_initcodecache();
struct lua_State *L = luaL_newstate();
luaL_openlibs(L); // link lua lib
int err = luaL_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);
config.thread = optint("thread",8);
config.module_path = optstring("cpath","./cservice/?.so");
config.harbor = optint("harbor", 1);
config.bootstrap = optstring("bootstrap","snlua bootstrap");
config.daemon = optstring("daemon", NULL);
config.logger = optstring("logger", NULL);
config.logservice = optstring("logservice", "logger");
config.profile = optboolean("profile", 1);
lua_close(L);
skynet_start(&config);
skynet_globalexit();
return 0;
}