skynet主體流程

  1. 初始化工作
    鎖,線程,信號的處理。

  2. 加載配置
    skynet會開啟一個(gè)全局專門用來加載配置的lua虛擬機(jī), 虛擬機(jī)加載配置文件,將配置項(xiàng)填充到一個(gè)配置數(shù)據(jù)結(jié)構(gòu)skynet_config中,具體過程請看下篇skynet加載配置文件。

  3. 調(diào)用skynet_start(skynet_config*)啟動日志模塊

    • a) 根據(jù)skynet_config初始化模塊路徑,time,socket,harbor等。
    • b) 根據(jù)日志配置啟動一個(gè)logger服務(wù),這是skynet進(jìn)程創(chuàng)建的第一個(gè)服務(wù)。

    加載服務(wù)的過程是:skynet_module_query('mod_name'),先查找該模塊是否已經(jīng)存在,不存在就根據(jù)路徑和名字加載該模塊,并確定所有的函數(shù)地址,放入modules這個(gè)全局變量中,他來管理所有的模塊加載,調(diào)用事宜。

    加載了模塊就需要通過skynet_module_instance_create創(chuàng)建一個(gè)模塊的實(shí)例,他會調(diào)用模塊的create函數(shù),對應(yīng)各個(gè)模塊一般就是創(chuàng)建相應(yīng)的結(jié)構(gòu)體。例如日志模塊log結(jié)構(gòu)體有文件句柄,slua模塊有l(wèi)ua虛擬機(jī)實(shí)例等。

    一個(gè)服務(wù)對應(yīng)一個(gè)skynet_context,一般模塊創(chuàng)建時(shí)也會創(chuàng)建一個(gè)skynet_context,然后進(jìn)行關(guān)聯(lián)。skynet_context結(jié)構(gòu)體有模塊和其實(shí)例字段。通過skynet_handle_register為每個(gè)skynet_context生成一個(gè)全局唯一的handle。然后就是為這個(gè)skynet_context創(chuàng)建并關(guān)聯(lián)一個(gè)消息隊(duì)列。

    接下來就是模塊實(shí)例進(jìn)行初始化:skynet_module_instance_init(mod, inst, ctx, param)。初始化時(shí)帶上ctx是為了給他設(shè)置回調(diào)函數(shù),以及在用skynet_command把全局handle_storage中的ctx.handler綁定一個(gè)名字。

    最后就是把生成的消息隊(duì)列加入到全局隊(duì)列中,這樣消息泵才能一直從里面獲取消息。以上就是創(chuàng)建一個(gè)服務(wù)的過程,代碼如下:

struct skynet_context * 
skynet_context_new(const char * name, const char *param) {
    struct skynet_module * mod = skynet_module_query(name);

    if (mod == NULL)
        return NULL;

    void *inst = skynet_module_instance_create(mod);
    if (inst == NULL)
        return NULL;
    struct skynet_context * ctx = skynet_malloc(sizeof(*ctx));
    CHECKCALLING_INIT(ctx)

    ctx->mod = mod;
    ctx->instance = inst;
    ctx->ref = 2;
    ctx->cb = NULL;
    ctx->cb_ud = NULL;
    ctx->session_id = 0;
    ctx->logfile = NULL;

    ctx->init = false;
    ctx->endless = false;
    // Should set to 0 first to avoid skynet_handle_retireall get an uninitialized handle
    ctx->handle = 0;    
    ctx->handle = skynet_handle_register(ctx);
    struct message_queue * queue = ctx->queue = skynet_mq_create(ctx->handle);
    // init function maybe use ctx->handle, so it must init at last
    context_inc();

    CHECKCALLING_BEGIN(ctx)
    int r = skynet_module_instance_init(mod, inst, ctx, param);
    CHECKCALLING_END(ctx)
    if (r == 0) {
        struct skynet_context * ret = skynet_context_release(ctx);
        if (ret) {
            ctx->init = true;
        }
        skynet_globalmq_push(queue);
        if (ret) {
            skynet_error(ret, "LAUNCH %s %s", name, param ? param : "");
        }
        return ret;
    } else {
        skynet_error(ctx, "FAILED launch %s", name);
        uint32_t handle = ctx->handle;
        skynet_context_release(ctx);
        skynet_handle_retire(handle);
        struct drop_t d = { handle };
        skynet_mq_release(queue, drop_message, &d);
        return NULL;
    }
}
  1. 調(diào)用bootstrap啟動slua模塊

    bootstrap函數(shù)中創(chuàng)建了一個(gè)新的服務(wù)--slua,過程與上面的一致,只是在初始化slua服務(wù)的時(shí)候,給他的消息隊(duì)列中發(fā)送了一條消息,參數(shù)為'bootstrap',是bootstrap函數(shù)傳入的。關(guān)于這條消息的作用,我們下篇再講。

  2. 根據(jù)配置線程數(shù)開啟一系列線程,包括工作線程,監(jiān)控線程,socket線程等等。工作線程一直不停的抓取消息并執(zhí)行消息。

  3. 清理釋放工作

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,545評論 19 139
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 30,224評論 8 265
  • 寫在前面 這篇文章是分析skynet框架,自己“用”skynet已經(jīng)有一年,項(xiàng)目中是以它為底層框架,上層使用lua...
    fooboo閱讀 13,436評論 1 14
  • 引言: 一直都是從事客戶端的開發(fā)工作,最近抽了點(diǎn)時(shí)間想了解一下服務(wù)器開發(fā)的相關(guān)知識,一番博客瞎逛之后,發(fā)現(xiàn)了一個(gè)不...
    linshuhe1閱讀 5,497評論 0 10
  • 2018年2月6號 星期一 天氣晴 今天由于晚了,沒有給女兒打電話。每次打電話都囑咐女兒要好好學(xué)習(xí),...
    藺雨菲媽媽閱讀 391評論 0 0

友情鏈接更多精彩內(nèi)容