skynet源码分析之lua层消息处理

Lua层消息处理机制在lualib/skynet.lua,提供大部分Lua层的api(最终会调用到c层的api),包括启动一个snlua服务时Lua层的处理,创建新服务,注册服务协议,如何发送消息,如何处理对方发过来的消息等。本篇主要介绍消息处理机制,从而理解skynet如何实现高并发。

为了简化,代码里用到的coroutine_resume,coroutine_yield看成coroutine.resume,coroutine.yield即可。

local coroutine_resume = profile.resume
local coroutine_yield = profile.yield

1. 协程

coroutine.create,创建一个co,唯一的参数是co要执行的闭包f,此时是不会执行闭包f的

coroutine.resume,执行一个co,第一个参数是co的句柄,如果是第一次执行,其他参数是传递给闭包f的。co启动后,一直执行直到它终止或让出。正常终止,返回true和闭包f的返回值;发生错误异常终止,则返回false和错误信息

coroutine.yield,使co暂停,让出执行权。对应最近的resume会立刻返回,返回true和yield的参数。下一次resume同一个co时,会从让出点继续执行,此时,yield的调用会立刻返回,返回值为resume除第一个参数之外的其他参数

引用Lua文档介绍协程coroutine(简称co)的经典例子,可以看出,co可以被不断的暂停和重启。skynet广泛使用co,当发送一个rpc请求时会暂停当前co,等对方返回时又重启co。

 

2. skynet创建协程的方式

先阐述下skynet创建协程(co)的方式,通过co_create(f)这个api创建一个协程,这段代码非常有意思。为了性能,skynet会把创建的co放到缓存里(第9行),当协程执行完流程(闭包f)后不会终止,而是暂停(第10行)。当调用者调用co_create这个api时,如果缓存里没有,通过coroutine.create创建一个co,此时是不会执行闭包f,然后在某个时刻(通常是收到消息调用消息分发skynet.dispatch_message)会重启(附带需要的参数)这个co,co接着执行闭包f(第6行),最后暂停以等待下一次使用,对应最近的resume返回true和“EXIT”(第10行);如果是一个复用的co,重启co(第15行,参数是将要执行的闭包f),yield会立刻返回把闭包赋值给f(第10行),在11行又暂停,同样在某个时刻会重启(附带需要的参数)这个co,co接着执行闭包f(第11行),最后又在第10行暂停等待下一次使用。

 1 -- lualib/skynet.lua
 2 local function co_create(f)
 3     local co = table.remove(coroutine_pool)
 4     if co == nil then
 5         co = coroutine.create(function(...)
 6             f(...)
 7             while true do
 8                 f = nil
 9                 coroutine_pool[#coroutine_pool+1] = co
10                 f = coroutine_yield "EXIT"
11                 f(coroutine_yield())
12             end
13         end)
14     else
15         coroutine_resume(co, f)
16     end
17     return co
18 end

推荐一个Skynet视频讲解:https://ke.qq.com/course/2806743?flowToken=1030833,讲解详细还有文档资料配套学习&#

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值