协同程序是什么?

2020-06-30 15:00发布

9条回答
蜗牛
2楼-- · 2020-06-30 16:29

协程语法怎样理解:

1.协程,顾名思义,就是“协同程序”,用来实现协作。 2.比如在游戏中需要等待1秒后执行一个操作。我们不能让游戏主线程卡死等1秒,而是开启一个协程进行协作,协程同样是由主线程来驱动(所以说它不是线程),会在每一帧去检测它是否已经达到了完成的条件。比如条件是1秒后执行一个操作,那么在1秒后主线程对它检测时。条件满足,于是就执行先前设定好的相关操作。

为什么要有协程?

  1. Uniy核心逻辑是单线程,为了开发便利,统一生命周期管理,不需要考虑锁的问题。

  2. 一些导步操作非常耗时,比如资源加载,如果让用户去使用多线程开发,整个开发逻辑会非常复杂。而通过协程封装起来,方便用户使用。并且对于一些耗废时间的操作,Unity会在引擎底层通过多线程去完成,而协程则通过不断的访问这个操作的状态判断加载是否完成。

启动协程的方法:

  1. StartCoroutine(IEnumerator routine)

  2. StartCoroutine(string routine)或StartCoroutine(string routine,object value) 通过传入函数名字的字符串启动协程的性能开销要更高,但这种方式启动的协程可以通过StopCoroutine(string methondname)来终止,这种方式还有一个限制就是只能传递一个参数。

协程终止的方法

  1. StopCoroutine(string methondname)只能终止通过字符串名字启动的协程

  2. StopCoroutine(Coroutine coroutine)

  3. StopAllCoroutines()终止所有协程

  4. 在协程内部终止可以使用

协程的一些特性

  1. 在一个协程中可以启动另一个协程

  2. 一个协程可以暂停另一个协程

  3. 两个协程也可以同时并行工作

  4. 协程在执行过程中可以通过yield在任何时间点暂停,yeild返回的值决定了协程何时恢复执行

  5. 在多个游戏帧循环中进行操作时,协程表现十分出色,几乎没有额外性能开销

  6. StartCoroutine()函数总是会立即返回,不管你yeild返回的值是什么

  7. 多个协程结束时的顺序是无法保证与其启动顺序一致的,即使他们是在同一帧当中结束

关于yeild返回的值

  1. 可以是null,数字 ,字符串,布尔值甚至表达式,函数,嵌套协程。

  2. 当return是一个函数调用,赋值表达式,嵌套协程时,会直接调用这个函数或表达式。

  3. 协程一般情况下是在Update调用完成之后运行,在yeild后面的条件满足之前,协程会一直挂起在那里。

  4. 不同的yeild返回类型对应了不同的条件:

    1. null,数字,字符串:会在下一帧所有Update()函数运行之后继续运行

    2. WaitForSeconds:延迟指定的时间之后,在所有的Update()函数运行之后继续运行

    3. WaitForFixedUpdate:在所有FixedUpdate() 函数运行之后继续运行。(注意这里不是指下一帧,因为FixedUpdate()的帧率和Update()是不一样的)

    4. WWWW:当WWW资源加载成功以后继续运行。(其它的异步资源加载函数也是一样)


  1. StartCoroutine:运行完成嵌套的协程以后再继续运行。


梅向南
3楼-- · 2020-06-30 15:36

协程全称协同程序,与线程类似,每一个应用程序都对应一个进程,每一个进程都有一个主线程,而协程在主线程之中,因而使用了还是单线程,不能理解为多线程,应是主线程的一部分。常用于使用动画时同步代码,时间等待,资源加载,场景切换等等。一般都用于等待一段时间执行后面的代码,或者等待资源加载完成执行后续的代码。

立志大灰狼
4楼-- · 2020-06-30 16:22

协程全称协同程序,与线程类似,每一个应用程序都对应一个进程,每一个进程都有一个主线程,而协程在主线程之中,因而使用了还是单线程,不能理解为多线程,应是主线程的一部分。常用于使用动画时同步代码,时间等待,资源加载,场景切换等等。一般都用于等待一段时间执行后面的代码,或者等待资源加载完成执行后续的代码。

老杜
5楼-- · 2020-07-01 09:11

主要用来做异步加载资源的,游戏中游戏加载比较耗时,所有用异步加载,这时候就用到了协程

Mantra
6楼-- · 2020-07-01 09:32

一。什么是协同程序

       协同程序,即在主程序运行时同时开启另一段逻辑处理,来协同当前程序的执行。换句话说,开启协同程序就是开启一个线程

 

二。协同程序的开启与终止

       在Unity3D中,使用MonoBehaviour.StartCoroutine方法即可开启一个协同程序,也就是说该方法必须在MonoBehaviour或继承于MonoBehaviour的类中调用。

       在Unity3D中,使用StartCoroutine(string methodName)和StartCoroutine(IEnumerator routine)都可以开启一个线程。区别在于使用字符串作为参数可以开启线程并在线程结束前终止线程,相反使用IEnumerator 作为参数只能等待线程的结束而不能随时终止(除非使用StopAllCoroutines()方法);另外使用字符串作为参数时,开启线程时最多只能传递 一个参数,并且性能消耗会更大一点,而使用IEnumerator 作为参数则没有这个限制。

        在Unity3D中,使用StopCoroutine(string methodName)来终止一个协同程序,使用StopAllCoroutines()来终止所有可以终止的协同程序,但这两个方法都只能终止该 MonoBehaviour中的协同程序。

        还有一种方法可以终止协同程序,即将协同程序所在gameobject的active属性设置为false,当再次设置active为ture时,协同程 序并不会再开启;如是将协同程序所在脚本的enabled设置为false则不会生效。这是因为协同程序被开启后作为一个线程在运行,而 MonoBehaviour也是一个线程,他们成为互不干扰的模块,除非代码中用调用,他们共同作用于同一个对象,只有当对象不可见才能同时终止这两个线 程。然而,为了管理我们额外开启的线程,Unity3D将协同程序的调用放在了MonoBehaviour中,这样我们在编程时就可以方便的调用指定脚本 中的协同程序,而不是无法去管理,特别是对于只根据方法名来判断线程的方式在多人开发中很容易出错,这样的设计保证了对象、脚本的条理化管理,并防止了重名。


男孩无衣
7楼-- · 2020-07-01 16:13

协同程序是一个加强版的方法。

2楼说的很清楚。
我都不知道补充啥了。



总之协程非常强大,一旦会用就离不开了。甚至连UPdate方法都不愿意用了。

元则清
8楼-- · 2020-07-03 16:21

协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。

协同是非常强大的功能,但是用起来也很复杂。


协同程序又称协程,即在主程序运行时同时开启另一段逻辑处理,来协同当前程序的执行。

协程是一个分部执行,遇到条件(yield return 语句)会挂起,直到条件满足才会被唤醒继续执行后面的代码。通俗点说:程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。

注意协程不是线程,也不是异步执行的。协程和 MonoBehaviour 的 Update函数一样也是在MainThread中执行的。

协同程序可以和主程序并行运行,和多线程有点类似。