skynet service_snlua.c 剖析

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服务创建的全过程。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。