zoukankan      html  css  js  c++  java
  • skynet源码解析(二)——启动流程

    对于你不了解的框架或者引擎,介绍再多的逻辑结构都好像有点茫然的感觉。所以小编认为,最有效的方式就是搞清楚框架启动流程的步骤,让自己心中有一条线可以牵引着。

    以下内容转载于网友分享的文档里说明。对小编来说,如获珍宝,在这里也分享给大家。

    启动流程的相关源代码在skynet-srcskynet_main.c 和skynet-srcskynet_start.c 这两个文件中。

    skynet_main.c 主要是设置环境和加载配置文件,最后调用skynet_start.c 文件中的 skynet_start() 函数启动 Skynet 服务程序。

    skynet_start.c 主要是初始化 Skynet 的各个组件,并创建监视线程、定时器线程、网络线程和工作线程。

    一、skynet_main.c 的流程如下:

    1、 从 main()入口函数开始。

    2、 skynet_globalinit() 全局初始化,这个函数在 skynet_server.c中定义,主要功能是为线程特有数据创建一个 Key。使用pthread_key_create()函数。并使用 pthread_setspecific()函数设置特有数据Key的Value 值。

    3、 skynet_env_init() 为初始化 Lua 的环境,这个函数在skynet_env.c 中定义,主要创建一个全局的数据结构 structskynet_env *E,并初始化结构的值。

    4、 sigign()为信号处理,主要是用于忽略 SIGPIPE 信号的处理。

    5、 从步骤 5 到步骤 11 主要是在 Lua 状态机中运行,lua_newstate(skynet_lalloc, NULL)表示,新建一个 Lua 状态机,并使用 skynet_lalloc()内存分配机制,这个定义在malloc_hook.c 中。

    6、 luaL_openlibs() 打开 Lua 的标准库。

    7、 luaL_loadstring(L, load_config) 用于加载一段Lua 脚本字符串,这个 lua 脚本主要用于打开名字为 config_file 的lua脚本用作 skynet 的配置文件。

    8、 lua_pushstring(L, config_file)主要是压入上面加载的 Lua 脚本字符串的参数 config_file,这个参数将由 main()函数的argv[1]参数定义。

    9、 lua_pcall(L, 1, 1, 0) 执行加载的 Lua 脚本字符串,这将会加载 config_file 定义的 lua 脚本用于 Skynet 的配置。

    10、 _init_env() 弹出 Skynet 配置脚本的 Key 和 Value,并设置为Lua环境变量,最后设置对应Key的值到struct skynet_config config 结构中,方便 skynet_start()调用时传入配置文件的参数。

    11、 lua_close(L) 关闭上面用 lua_newstate()创建的 Lua 状态机。

    12、 skynet_start()传人配置参数并启动 Skynet 的各个组件和线程。这个函数定义在 skynet_start.c 文件中。

    13、 skynet_globalexit()对应上面的 skynet_globalinit(),用于删除线程存储的 Key。

    二、skynet_start.c 的流程如下:

    1、skynet_start()启动函数,由 main()函数调用。

    2、daemon_init()初始化守护进程,由配置文件确定是否启用。这个函数定义在 skynet_daemon.c 中。

    3、skynet_harbor_init()初始化节点模块,用于集群,转发远程节点的消息。这个函数定义在 skynet_harbor.c 中。

    4、skynet_handle_init()初始化句柄模块,用于给每个 Skynet 服务创建一个全局唯一的句柄值。这个函数定义在 skynet_handle.c 中。

    5、skynet_mq_init()初始化消息队列模块,这是 Skynet 的主要数据结构。这个函数定义在 skynet_mq.c 中。

    6、skynet_module_init()初始化服务动态库加载模块,主要用于加载符合 Skynet 服务模块接口的动态链接库。这个函数定义在skynet_module.c 中。

    7、skynet_timer_init()初始化定时器模块。这个函数定义在skynet_timer.c 中。

    8、skynet_socket_init()初始化网络模块。这个函数定义在skynet_socket.c 中。

    9、skynet_context_new(logger)加载日志模块。这个函数定义在skynet_server.c 中。

    10、bootstrap()加载引导模块。主要在 Skynet 配置文件中定义,默认定义为 bootstrap = "snlua bootstrap",表示引导程序将加载snlua.so 模块,并由 snlua 服务启动 bootstrap.lua 脚本。如果不使用snlua 也可以直接启动其它服务的动态库。

    11、_start()函数中创建_monitor()监视线程。线程用 create_thread()创建,create_thread()封装了系统函数 pthread_create()。

    12、_start()函数中创建_timer()定时器线程。

    13、_start()函数中创建_socket()网络线程。

    14、_start()函数中创建_worker()工作线程。工作线程的数量由Skynet 配置文件中的 thread = 8 定义。一般根据服务器的 CPU 核数来设置。

    15、skynet_socket_free()释放网络模块。

    16、daemon_exit()退出守护进程。这个根据 Skynet 配置文件的需要,决定是否启用。

    下图为 skynet_start.c 的整个执行流程:主要功能就是初始化Skynet 的各个组件模块,然后启动监视线程、定时器线程、网络线程和工作线程。

    以上就是skynet框架的启动流程,这里采用的是广度优先遍历的方式进行解析,这个方式对于解析框架来说确实是一种很好的学习方式。我们先不管这个接口内部的具体,我们先了解这个接口是做什么。把第一层模块都弄清楚之后,在深入到每个接口去理解。

    更多精彩内容,请关注同名公众:一点月光(alittle-moon)

  • 相关阅读:
    css3新特性
    线程间通信的三种方法
    硬件相关知识
    time.h
    ldr指令总结
    你不知道的100个小秘密
    ARM学习日记
    C中位域的使用
    《编程之美》第2刷勘误
    排序2
  • 原文地址:https://www.cnblogs.com/kiwiblog/p/14542035.html
Copyright © 2011-2022 走看看