详细解说协程例子

来源:互联网 发布:cae分析软件 编辑:程序博客网 时间:2024/06/05 06:30
function foo(a)    print("foo", a)    return coroutine.yield(2 * a)endco = coroutine.create(function ( a, b )    print("co-body", a, b)    local r = foo(a + 1)    print("co-body", r)    local r, s = coroutine.yield(a + b, a - b)    print("co-body", r, s)    return b, "end"end)print("main", coroutine.resume(co, 1, 10))print("main", coroutine.resume(co, "r"))print("main", coroutine.resume(co, "x", "y"))print("main", coroutine.resume(co, "x", "y"))-----------------------------------------LOG---------------------------------------------下面我们看log逐行分析:①打印出来co-body   1  10顾名思义就是简单的传参赋值的过程②打印出foo 2  原理同①③当我们把挂起的协成通过resume()唤起的时候此时返回值 第一个参数为true 后面的变长参数为 yield()函数的参数 所以出现  true  4④这块就是协成的关键点当我们在调用yield()函数的时候有其他协成的时候可以切换到其他协成 然后再通过resume方法重入(reenter)到上次调用yield的地方,并且把resume()的参数当成返回值传给了要重入(reenter)的协程 所以第③的入口是从上一次yield()函数的返回值处切入的参数为 r 并且返回 因此打印出 co-body r⑤子例程的起始处是唯一的入口点,一旦return就完成了子程序的执行,子程序的一个实例只会运行一次。 因为在④中我们从foo()函数的返回值处切入的所以我们可以走到下一次的yield()函数因此 返回值第一个为 true 后面的返回值为传入到yield()函数的参数, 可能有的同学在这比较疑惑 a, b此时还有值么别忘了我们协成有一个重要的关键点就是符合堆栈的基本准则,并且共享变量信息 所以此时 打印出  true 11 -9⑥此时看起来已经是从 print("main", coroutine.resume(co, "x", "y")) 切入了《大家思路慢慢缕清》 我们在④中说协成会在上一次切换协成的返回处作为切入点所以这次我们在下一个yield()函数返回值处并且把resume()的参数作为返回值 所以此时输出了 co-body x y⑦这里函数没有return所以正常的逻辑走 我们要明确一个概念就是 yield()-> resume()之间的转化关系 简单点的来说就是 我们在 print(yield())的时候如果不出错那么第一个参数我们会返回true 然后 是 b  和  end⑧这个是一个关键点我们一直在说 yield()函数是起到切换协成的作用那么我们来捋顺一下 第一个yield()来切换第二个协成第二个yield()来切换第三个协成然而我们只有两个yield()所以不能够在切换协成了此时终止了所以我们看一下coroutine.status就可以看到已经dead了----大家在测试的时候可以分批次的打印log
0 0
原创粉丝点击