skynet 源码分析-启动流程之线程池启动
Last updated
Last updated
在上一节启动了 skynet 的服务之后, 这些service 就要开始工作了, 主要是启动了工作线程, 启动的过程比较简单, 所以主要讲这些线程是如何工作的
thread 就是配置文件中 thread参数, 工作线程数
pid[thread+3] 这里的 3 是为了下面启动monitor, timer, 和socket 用的, 前半部分就是初始化 mutex, cond
count: 工作线程数
m: 存储与每个线程的监控信息
cond: 工作线程会等待这个 cond 知道被唤醒
mutex: 锁
sleep: 空闲线程数
quit: 是否退出标志位
这里的 monitor_check 是skynet 检查死循环的机制, 每次进入时 check_version 被赋值, 如果下一次check_version 和 version 相同, 就说明两个服务之间可能一直在往来发送这个消息没有处理, 就会把这个 handle对应的context 释放, 结束死循环
skynet_monitor_trigger 就是操作version 的地方, 在每次执行线程操作的时候会对这个原子量+1
timer 比较容易, 就是不停的在更新全局timer 和 socket_server 的时间戳, 定时任务就是靠这个更新的时间戳工作, 136行的wakeup 就是来唤醒线程的
这里监听的全局 socket(之前创建的pipe), 当有事件发生时, wakeup唤醒线程, 这里的 skynet_socket_poll 方法是 epoll 在监听 pipe, 之后skynet 的网络通信部分会讲到
thread_worker 在启动前, 绑定了全局的 monitor, 分配了每个线程的权重 weight, 用来配置每个线程的占用, 这里thread_worker 主要逻辑是: 不断地从全局的 message_queue中取任务并执行 (skynet_context_message_dispatch), 当空闲时 wait 在条件变量 cond 处, 往复执行,具体任务是如何添加和取出并执行会在skynet 任务调度处详细讲解