本篇大概讲一下 skynet 进程的启动流程,完全了解启动流程基本上也就明白了 skynet 的原理了,本篇会大概提到全部的启动流程。
main
所有 C 程序的可执行入口都是 main 函数,skynet 的 main 函数在 skynet_main.c 中实现,来看一下它执行了哪些操作。
|
|
虽然有一点长,但是在 main 函数中做的工作并不是非常多,其它更多关于启动服务要进行的初始化工作会交给最后调用的 skynet_start
函数来执行。在 main 函数中最主要做的是三件事。
- 解析配置文件
- 将解析的结果保存在环境变量里
- 使用解析的结果调用
skynet_start
继续进行后续的初始化
skynet_start
|
|
在 skynet_start
中,主要的操作是将剩余的全局变量都进行了初始化。然后调用了 bootstrap
和 start
来继续处理后续的工作。
bootstrap
在看源码之前,先来关注一下 bootstrap
函数的调用方法。
|
|
参数 ctx
是刚刚创建的 logger 服务,参数 config->bootstrap
的内容是配置文件里指定的启动命令,在 skynet 给出的默认配置文件中,这个命令是 snlua bootstrap
。
了解清楚了参数的内容,再来看一下 bootstrap
的源码。
|
|
源码非常简单,主要做了两件事情,首先从参数中获取要启动的服务和要传给服务的启动参数,然后创建了这个服务。在默认配置下就是创建了一个 snlua
服务,参数为 bootstrap
。
关于在这个名为 bootstrap
的 lua 服务中会进行的操作,后续的文章中会专门讲解。
start
start
函数接收的参数是配置文件中指明的 worker 线程的数量。
|
|
这个函数虽然比较长,但是进行的操作并不复杂,它启动了所有类型的线程,一共是 3 + N 条,然后使用了 pthread_join
等待所有线程结束,主线程后续会一直阻塞在这里,不会进行其它操作。其中使用的 create_thread
只是对 pthread_create
的简单封装,就不展开说了。
还有一点需要注意的是 weight
数组,它定义了 worker 线程的工作权重。在 worker 线程创建的时候,数组里对应的权重被传给了线程的启动函数。关于这个权重的用途,后续讲 worker 线程作用的文章中会提到。