skynet源码解析(三)——启动流程
对于你不了解的框架或者引擎,介绍再多的逻辑结构都好像有点茫然的感觉。所以小编认为,最有效的方式就是搞清楚框架启动流程的步骤,让自己心中有一条线可以牵引着。
当你在终端输入./skeynet example/config的时候,就开始启动skynet了。那么skynet是从哪个文件的哪个函数开始运行呢?这里如果大家不知道的话可以用gdb的方式在main函数中打断点,像下面这样
b main
因为任何c/c++的进程都是main函数这个入口开始的,所以我们可以知道skynet框架是从skynet_main.c这个文件的main函数开始的。
以下内容转载于网友分享的文档里说明。对小编来说,如获珍宝,在这里也分享给大家。
启动流程的相关源代码在skynet-src\skynet_main.c 和skynet-src\skynet_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)
skynet源码解析(三)——启动流程相关推荐
- android 输入法如何启动流程_android输入法02:openwnn源码解析01—输入流程
android 输入法 02:openwnn 源码解析 01-输入流程 之后要开始 android 日文输入法的测试,因此现在开始研究 android 输入法.之前两 篇文章已经对 android 自 ...
- bluetoothd源码剖析(一)启动流程
蓝牙系列: bluez调试笔记_weixin_41069709的博客-CSDN博客_bluezbluez移植https://blog.csdn.net/weixin_41069709/article/ ...
- Retrofit2源码解析——网络调用流程(下)
Retrofit2源码解析系列 Retrofit2源码解析(一) Retrofit2源码解析--网络调用流程(上) 本文基于Retrofit2的2.4.0版本 implementation 'com. ...
- Disruptor源码解析三 RingBuffer解析
目录 系列索引 前言 主要内容 RingBuffer的要点 源码解析 系列索引 Disruptor源码解析一 Disruptor高性能之道 Disruptor源码解析二 Sequence相关类解析 D ...
- OkHttp3源码解析(三)——连接池复用
OKHttp3源码解析系列 OkHttp3源码解析(一)之请求流程 OkHttp3源码解析(二)--拦截器链和缓存策略 本文基于OkHttp3的3.11.0版本 implementation 'com ...
- 并发编程与源码解析 (三)
并发编程 (三) 1 Fork/Join分解合并框架 1.1 什么是fork/join Fork/Join框架是JDK1.7提供的一个用于并行执行任务的框架,开发者可以在不去了解如Thread.R ...
- ReactiveSwift源码解析(三) Signal代码的基本实现
上篇博客我们详细的聊了ReactiveSwift源码中的Bag容器,详情请参见<ReactiveSwift源码解析之Bag容器>.本篇博客我们就来聊一下信号量,也就是Signal的的几种状 ...
- 拆轮子-RxDownload2源码解析(三)
本文为博主原创文章,未经允许不得转载 造轮子者:Season_zlc 轮子用法请戳作者链接 ↑ 前言 本文主要讲述 RxDownload2 的多线程断点下载技术. 断点下载技术前提 服务器必须支持按 ...
- 前端入门之(vuex源码解析三)
上两节前端入门之(vuex源码解析二)我们把vuex的源码大概的撸了一遍,还剩下(插件.getters跟module),我们继续哈~ 插件童鞋们可以去看看vuex在各个浏览器的状态显示插件,小伙伴可以 ...
最新文章
- 第十六届全国大学生智能车竞赛航天智慧物流竞赛成绩与奖项
- 使Chrome接受自签名的本地主机证书
- jre java.security_java.security.NoSuchProviderException: no suc...
- Can not create a Path from an empty string解决
- 小红书公司注册老红书商标上热搜 网友:过两年变老了改名吗?
- 三分钟训练眼球追踪术,AI就知道你在盯着哪个妹子 | TensorFlow.js代码
- 什么是延展性(Malleability,可鍛性)
- C# 电子白板软件开发
- Bodymovin插件的使用
- 全民K歌神器,这款麦克风唱享高音质体验
- vant-ui 有赞ui官网打不开?
- 简简单单做股票读书笔记(1/8)
- Android 开发都有哪些好书值得一读?
- Machine Learning with Graphs 之 Random Walk with Restarts and Personalized PageRank
- Eve-NG No IP address on interface pnet0
- ROS发布/订阅Float64MultiArray数组类消息(C++和Python相互发布和订阅)
- Photon在unity中的使用
- 计算机网络及多媒体知识,计算机基础知识:多媒体的基本概念及关键技术
- java祖冲之加密算法_对称加密和非对称加密
- 龙芯回应电脑脱销质疑:不应与假汉芯相提并论
热门文章
- Unity Dotween插件的运动曲线(Ease)介绍Ease选项Ease效果示例以及C#修改动画曲线功能
- Apache 降权 禁用php,什么是降权?
- 管理寓言:海马的焦虑!
- 【颇尔】Stax mAx深层过滤平台
- SQL内连接与外连接
- 【视频资源】c语言全套高清视频打包下载,希望对正在学习c语言的朋友有帮助...
- 关于Dagger2的一些个人理解
- WordPress博客主题:Free 1白色两栏自适应模板
- 2021-09-20 BeagleBone 系列 简介
- 高斯投影是这个“oblique conformal cylindrical”么?