1. snlua 是什么?作用是什么?
首先先看下snlua的结构体
service_snlua.c下的结构体如下:
// service_snlua.c
struct snlua {
lua_State * L;
struct skynet_context * ctx;
size_t mem;
size_t mem_report;
size_t mem_limit;
};
而在lua_skynet.c中的结构体如下:
// lua_skynet.c
struct snlua {
lua_State * L;
struct skynet_context * ctx;
const char * preload;
};
可以看到snlua结构体主要是绑定 lua_State 与 skynet_context 的功能。
snlua 用来创建lua服务,一个lua服务对应一个lua虚拟机。
在skynet_context 中会绑定对应的snlua对象,从而找到对应的lua_State,如下:
// skynet_server.c
// 举例snlua
struct skynet_context {
void * instance; // 这里表示snlua对象
struct skynet_module * mod; // 保存的是snlua中的处理函数
void * cb_ud; // snlua对象
skynet_cb cb;
struct message_queue *queue;
FILE * logfile;
char result[32];
uint32_t handle;
int session_id;
int ref;
bool init;
bool endless;
CHECKCALLING_DECL
};
2. 启动一个lua服务的过程是怎样的?
在skynet中创建一个lua服务:
skynet.newservice("xxx", "xxx")
接下来列出调用堆栈:
// skynet.lua
function skynet.newservice(name, ...)
return skynet.call(".launcher", "lua" , "LAUNCH", "snlua", name, ...)
end
// launcher.lua
local function launch_service(service, ...)
local param = table.concat({...}, " ")
local inst = skynet.launch(service, param)
...
return inst
end
// manager.lua
function skynet.launch(...)
local addr = c.command("LAUNCH", table.concat({...}," "))
...
end
function command.LAUNCH(_, service, ...)
launch_service(service, ...)
return NORET
end
// skynet_service.c
static const char *
cmd_launch(struct skynet_context * context, const char * param) {
size_t sz = strlen(param);
char tmp[sz+1];
strcpy(tmp,param);
char * args = tmp;
char * mod = strsep(&args, " \t\r\n");
args = strsep(&args, "\r\n");
struct skynet_context * inst = skynet_context_new(mod,args);
...
}
// skynet_server.c
struct skynet_context *
skynet_context_new(const char * name, const char *param) {
struct skynet_module * mod = skynet_module_query(name); // 创建snlua的模块
if (mod == NULL)
return NULL;
void *inst = skynet_module_instance_create(mod); // 调用snlua中的snlua_create函数来创建要创建的service的lua_State。
...
// 创建该服务的次级消息队列
struct message_queue * queue = ctx->queue = skynet_mq_create(ctx->handle);
...
CHECKCALLING_BEGIN(ctx)
int r = skynet_module_instance_init(mod, inst, ctx, param); // 初始化要snlua数据
...
}
上述即一个lua服务创建的全过程。