skynet之协程池(co_create)

4 篇文章 0 订阅
local coroutine_pool = {}
local coroutine_yield = coroutine.yield

local function co_create(f)
    local co = table.remove(coroutine_pool)
    if co == nil then
        co = coroutine.create(function(...)
            f(...)
            while true do
                f = nil
                coroutine_pool[#coroutine_pool+1] = co
                f = coroutine_yield "EXIT"
                f(coroutine_yield())
            end
        end)
    else
        coroutine.resume(co, f)
    end
    return co
end

这段代码是创建协程的,并把创建出来的协程自动加到一个pool里。

-- test code
print(#coroutine_pool)

local co1 = co_create(function() print("111111") end)
print(coroutine.status(co1))
print(coroutine.resume(co1))

print(#coroutine_pool)

local co2 = co_create(function() print("222222") end)
print(coroutine.resume(co2))

print(co1, co2)
print(#coroutine_pool)

result:

0
suspended
111111
true    EXIT
1
222222
true    EXIT
thread: 0086F890    thread: 0086F890
1

测试代码中,第一行先打印出coroutine_pool的数量,当然是0。
下面一行,使用co_create创建一个协程,状态为suspended, 然后调用resume启动,这时打出1111111,然后执行到while true里后,先把赋值为nil(这句没有应该也一样),再把co放到pool里,然后调用yield使协程挂起,并返回EXIT给调用resume的地方。

再下一行,打印出pool的数量为1.


local co2 = co_create(function() print("222222") end)

这一行创建了第二个协程,进入co_create函数后,第一行首先从pool里弹出一个co, 由于此时pool里有1个协程了,所以if条件走到了else那里,在这里面直接调用resume恢复协程的运行,并把执行函数f作为参数传递进去,这个resume会回到之前挂起的地方执行,也就是

f = coroutine_yield "EXIT"

这一行,yield返回的值是resume传进来的,也就是co2的执行函数,这里就是我写的print(‘222222’)那个函数。

再看下一行:

f(coroutine_yield())

这里马上又调用了一个yield是为什么呢?这是为了模拟真实coroutine.create的行为,协程创建后是挂起的,必须由外部调用resume才会运行。所以我们创建的co2这时就挂起在这一行了,f(…)还没运行。

之所以要把yield的参数传给f, 是为了模拟coroutine.resume的行为,在resume时,除了第一个参数co, 后面的参数都会传给协程的执行函数,这里这样写可以达到同样的效果,非常聪明的写法。


回到测试代码:

print(coroutine.resume(co2))

这里再次恢复协程的运行,打印出
222222
true EXIT

while true do
    f = nil
    coroutine_pool[#coroutine_pool+1] = co
    f = coroutine_yield "EXIT"  --再次停在这里,如此反复
    f(coroutine_yield())
end

下面一行

print(co1, co2)

打出来的结果是
thread: 006DF890 thread: 006DF890

我们已经知道co1和co2是同一个thread了,这里验证一下。

最后再打出pool的数量,仍然是1.


以上就是对skynet中co_create这个函数的分析了,lua中的coroutine理解起来还是比较费劲的,
我是花了挺长时间看这段代码的,这里做个备份,方便以后查阅。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值