skynet - 多线程 Actor 模型

skynet_start.c

skynet-src/skynet_start.c 实现了 skynet 的多线程工作机制和任务调度

是 skynet 多线程 Actor 模型的运行载体

skynet 的线程

skynet 主要有以下线程:

序号线程说明
0 号线程thread_monitor检测服务(Actor)是否死锁
1 号线程thread_timer2500微妙唤醒一次,执行定时器(push 定时器消息给 Actor)
2 号线程thread_socket处理 epoll 网络数据接收发
3 号线程开始(配置根数量)thread_worker工作线程。并发处理 Actor 消息

skynet 服务(Actor)

工作线程执行的都是 Actor 消息处理

在 skynet 中以下都是 Actor 同义词

命名语言说明
modulec++skynet c++ 层, module 就是一个 Actor
serviceluaskynet lua 层, 服务就是一个 Actor
skynet_contextc++module service 都是用 skynet_context 实例。所说的 Actor 实际上指的就是这货
actor口语skynet 是 Actor 模型的一个实现,因此交流中都会用 Actor 来表示代码中的 service 或 module

module 和 service 还有一点区别:

  • service 由 skynet 的 module snlua 创建
  • 每个 service 有自己的 lua 虚拟机,因此运行环境完全独立

Actor 模型中, Actor 间通过消息交互。因此 skynet 的 module service 均有自己的消息队列

全局消息队列

为了能让 Actor 高性能并发执行, skynet 中设置了全局消息队列

  • 全局消息队列中,存放的是 Actor 的消息队列
  • Actor 的消息队列,存放的是消息

工作线程,要执行 Actor 消息,首先从全局消息队列摘取 Actor 的消息队列

  • 这样,不会有同时 2 根线程执行同个 Actor 消息
  • 因此 Actor 消息执行过程也就不需要加锁
  • 不同 Actor 消息可以并发执行

工作线程工作流程

伪代码:

while
  Actor 消息队列 = pop 全局消息队列
  如果有
        执行 Actor 消息( n 条)
        push 消息队列回全局消息队列
  否则
        sleep

skynet 工作线程优先级

为了让每个 Actor 公平分配到 cpu ,防止饿死情况

skynet 给工作线程设置了优先级

启动工作线程时,会赋值 weight 确定其优先级

weight哪些线程执行的消息数量说明
-1[3, 6]号线程1 条 Actor 消息。这 4 根是保底每个 Actor 不会被饿死
0[7, 10]号线程以及 [35, 无穷大)号线程之后的线程本次 Actor 消息队列中的所有消息最高性能的方式
1[11, 18]号线程1/2 条
2[19, 26]号线程1/4 条
3[27, 24]号线程1/8 条

工作线程唤醒机制

工作线程在没消息后,会 sleep

通过以下重新唤醒:

  • thread_timer ,每 2500 微妙,检查如果有 sleep 线程,会随机唤醒 1 根
  • thread_socket ,有网络消息了,检查如果所有的线程均在 sleep ,会随机唤醒 1 根

工作线程死锁检查机制

每根线程维护着,消息处理次数(版本号)

thread_monitor 每 5 秒检查 1 次,如果版本号不变,打印日志警告,有线程可能死锁了

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fananchong2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值