深刻浅出!从语义角度分析隐藏在Unity协程背后的原理

Unity的协程使用起来比较方便,可是因为其封装和隐藏了太多细节,使其看起来比较神秘。好比协程是不是真正的异步执行?协程与线程究竟是什么关系?本文将从语义角度来分析隐藏在协程背后的原理,并使用C++来实现一个简单的协程,以揭开协程的神秘面纱。(文内代码为截图,可点击放大查看。)node

1、什么是协程编程

简单来讲,协程是一个有多个返回点的函数。通常来讲一个函数只有一个返回点,函数的调用者调用一次后,函数的生命周期就结束了。而对于协程来讲,其生命周期由调用者来决定,能够经过返回值来决定如何进行一次调用以及如何结束调用。闭包

因为协程返回的是一系列的值,每个yield return对应一次返回。用迭代器做为返回类型是比较好的选择,能够简单的认为每个yield return对于了迭代器中的一个元素。异步

Unity的C#代码中一个协程的返回值一般是IEnumerator类型,IEnumerator 接口有两个方法,分别是 Current 和 MoveNext。咱们能够简单的认为:协程就是一个返回迭代器的函数,一开始迭代器的Current指向函数的开头,每执行一次MoveNext,Current就指向下一个yield return 返回的值。例如:函数

2、协程的核心,神奇的yield线程

咱们来看看上而代码示例中的函数coroutine:翻译

上面代码神奇的地方在于关键词yield,为何能够调用屡次yield return返回一组值,而且该函数的返回值变成了Enumerator类型?这其实就是隐藏在协程背后的核心原理。有不少关于协程的核心原理的分析及实现的文章,大多都是从系统底层的角度来分析,使用了汇编,goto语句或者是C 语言的 setjmp 和 longjmp来实现了协程,虽然分析得比较透彻,但对读者所掌握的知识要求比较高,其中的一些概念比较晦涩,难于理解。设计

实际上从语义角度来看,协程的工做原理比较简单,任何支持闭包的语言均可以实现协程。下面咱们从语义的角度来解释协程:orm

1.每个yield return被包装成一个函数(简称为Y函数),若是该函数使用了外层的局部变量,将造成一个闭包协程

2.Y函数的返回值为yield传入的对象和下一个yield return所包装成的函数

3.对迭代器的MoveNext调用等价于对Y函数的调用

4.最后一个yield return包装成的Y函数返回yield传入的对象和一个空函数以表明迭代结束(即调用MoveNext时返回false)

3、简单协程的C++实现

如下是根据协程在语义上的解释,用C++的实现一个简单协程示例:

一共不到60行代码,就实现了简单的协程。对于上示例中的coroutine函数,除了语法上有一些差别,语义已经和C#的协程彻底一协了,甚至咱们能够引入一个宏让其长得更像C#的协程,例如:

虽然以上代码段看起来已经比较像Unity的协程了,可是遗憾的是代码还不够简洁,有一点点语法噪音(函数的结尾部分多了一些没意义的括号)语法也不够统一(最后一行是return yield)。

4、For循环

第三节咱们讲了协程的简单的实现,可是若是咱们若是在for循环中使用yield还存在问题,好比如下代码段:

coroutine1函数返回的迭代器中只包含一个值1,而不是咱们指望的1~10。所以对于协程中的循环咱们须要特殊处理。分析以上代码,咱们指望的是对于循环中的每个i,调用yield生成一个coroutine node,而后将这些node合并成一个链表返回。所以咱们能够将协程中的for语句翻译成一个For函数,代码以下:

Combine函数实现将两个Coroutine Node链接在一块儿合并成一个链表返回,其定义代码以下:

有了For函数,能够将coroutine1实现能够改为以下:

虽然在语法上该函数有一些丑,可是是从语义上彻底是等价如下C#代码的:

如下是一个更加复杂的示例:

语义上等价的C#代码为:

5、总结

本文从语义的角度来解释了协程的运行机制,并使用C++实现了简单的协程,但仍有部份内容未讨论到,好比怎样在For循环中实现break,yield break等,其实要实现这些并不困难,感兴趣的同窗能够自行去研究。

回到引言中提到的两个问题:

协程是否为异步执行?严格意义上来说,协程并非异步执行的,可是调用者能够分时间片去执行每个yield,让程序看起来像是异步的。协程和线程是什么关系?协程与线程之间没有严格的对应关系,可是能够结合使用,隐藏一些没必要要的细节以简化编程,好比unity的WWW。

来源:公众号<Gad-腾讯游戏开发者平台>

做者:Tseclam

原题:程序|深刻浅出!从语义角度分析隐藏在Unity协程背后的原理

产品经理必读文章

一份鹅厂产品经理自我成长的文档

腾讯内部培训手册:产品经理晋升路上的那些坎儿

重磅干货|QQ运营女王:小白到大神,要跨过哪些坑

不声不响我就当了产品经理......

腾讯产品法则:从需求分析到需求管理,作产品需求最全的方法都在这了

为什么有些产品经理画的线框图总被吐槽

什么是「好产品」?

陈会华:写给喜欢数据分析的初学者

体验至上的时代,交互设计师能为游戏作点什么?

熊一冬:作网游不是开宝箱-产品运营大循环思

相关文章
相关标签/搜索