Unity Coroutine explain (a)

Unity in coroutines is a very powerful feature, its main function is to call for a delay of game execution flow of events or a series of time intervals, for example, the story dialogue. A brief summary of several co-related knowledge process designed to enhance memory, as well as beginners doubts.

 

1, coroutine, process and thread

This is a frequently asked interview questions: the difference between coroutines, processes and threads in what?

  Speaking coroutine, we first review the following threads and processes these two concepts. In the operating system (os) level, there is a process (process) and thread (thread) two but we do not see the actual existence of "things", these two things are used to simulate the "parallel" and write an operating system programmers computing resources by using a certain strategy to different processes and threads allocated CPU, allowing users to "that" several different things, "while" in. "on a single CPU, the code os is forced to a process or thread is suspended, and replaced with another to calculate, so, in fact, is a serial, but "parallel conceptual." multicore cpu now on, the thread may be "truly parallel."

The process has its own independent stack and heap, the heap is neither shared nor shared stack, the process by the operating system scheduler.

Thread has its own independent stack and heap share, shared stack, the stack does not share, increased from the operating system thread scheduling (standard thread yes).

Coroutine shared heap and like threads, not shared stack, coroutine display scheduling coroutine code by the programmer.

An application generally corresponds to a process, a process generally have a main thread, there are several secondary thread between the thread is running in parallel, which can be turned on in the thread coroutines, let the program run at a specific time.

 

Difference coroutine and threads are: coroutine avoid meaningless schedule, which can improve performance, but because the programmer must take responsibility for their own schedule, at the same time, coroutine also lose the ability to use standard multi-CPU thread .

Analogy it is assumed that there is an operating system, a single core, the system does not need to run other programs, there are two threads A and B, A and B takes 10 seconds to run alone to complete their task, and tasks are arithmetic operations, there is no question of competition and sharing of data between AB. AB now two parallel threads, the operating system will stop AB switch between the two threads, to achieve a pseudo parallel effect switching frequency is assumed once per second, 0.1 second switching cost (mainly switching stack ), a total of 20 + 19 * 0.1 = 21.9 seconds. If coroutine way, you can run coroutine A, A gives way to the end of the coroutine B, switching occurs only once, the total time is 20 + 1 * 0.1 = 20.1 seconds. If the system is dual-core, and the thread is a standard thread, so you can really AB two threads in parallel, the total time of only 10 seconds, while the coroutine program still needs 20.1 seconds.

 

  In fact, it is fundamental, the coroutine in addition to the name, and the thread is not much contact. Unity in particular that all scripts and code that is running in a main thread, the coroutine is no exception. Thread coroutine similarities in that only coroutine seems to be performed in parallel with other functions. But essentially, the thread is through the implementation of the program at the same time can open multiple child threads to achieve parallel. And coroutine each frame is detected by the way, switching between themselves and other functions. This "running back and forth" approach, with a style used in Unity there is a clear order of execution (script lifecycle) does not look uniform. But this is its powerful place, so that when we do not have to use the coroutine lock consider the issue, and many other threads.

 2, the implementation of the principle of coroutine

unity in the coroutine execution by yield return XXX, will suspend the program, to perform the following content, attention coroutine not thread, before it is experiencing yield return XXX statement coroutine amount of methods and general approach is the same, that is, after the execution of the program to yield return XXX statement, then will perform is StartCoroutine () method after the program, or taking the single-threaded mode, only the contents of the statement following the yield return XXX temporarily suspended, wait until a specific time to perform.
So when it suspended the program execution, which depends on the life cycle of the monoBehavior.

The main program is coordinated after the update () method, before lateUpdate () method call, then we pass a small example to understand it.

using UnityEngine;
using System.Collections;
using System.Threading;
public class test : MonoBehaviour
{

    void Start()
    {
        StartCoroutine(tt());//开启协程
        for (int i = 0; i < 200; i++)   //循环A
        {
            Debug.Log("*************************" + i);
            Thread.Sleep(10);
        }
    }

    IEnumerator tt()
    {
        for (int i = 0; i < 100; i++) //循环B
        {
            Debug.Log("-------------------" + i);
        }

        yield return new WaitForSeconds(1); //协程1

        for (int i = 0; i < 100; i++) //循环C
        {
            Debug.Log(">>>>>>>>>>>>>>>>>>>>" + i);
            yield return null ; // coroutine 1 
        } 
    } 

    // update data 
    void the Update () 
    { 
        Debug.Log ( " the Update " ); 
    } 

    // after the updates 
    void LateUpdate () 
    { 
        Debug.Log ( " ------ LateUpdate " ); 
    } 

}

Operating results of the program are:

Method B first execution cycle, then the execution cycle A, and then perform update () and lateUpdate (), and after waiting 1S, loop C is performed in the output between updat () () and lateupda.

 

3, different types of return yield return

  Using the yield return of the time you will find a long list of the type which can be returned for a beginner I think that with a new divided and without a new line of the.

  First say the new band. Typically there may be null, numbers, strings, Boolean even expressions, functions, etc. nested yield return the coroutine.

  以在Start()中开启当前协程为例,如果是不带new的返回类型,执行时间都是一样的。即在第一时间执行协程中的代码 到第一个yield return当行为止,然后在下一帧的Update之后,LateUpdate之前执行yield return后面的代码。

  另外需要注意的是,yield return后面可以是一个函数调用,赋值表达式,嵌套的其它协程等。以赋值的表达式num=10为例;它会在当行yield return执行的时候就执行,函数调用和其它协程也是一样。也就是说,此时yield return的函数调用就相当于直接调用了这个函数,并且是当时就执行的。 而其它return 类型 如null,字符串,数字等一般只用作延迟一帧来用,其它作用,待我后期再研究下。

  下面说带new的,也是通常我们重点使用的协程功能。

   这里列举几个:

  (1)new  WaitUntil(Func<bool>)  参数是一个布尔返回类型的委托,作用是,知道这个返回的布尔值为true时,协程才会继续执行当行yield return 后面的代码。       

  (2) new WaitForSeconds(float)参数是float类型的数字,表示秒,也是协程最常用的功能之一。 作用是,在N秒后才会继续执行当行yield return 后面的代码。 

由于yield return可以在一个协程中任意位置写多个,配合这个可以实现很多时间细化可视化的功能。

  (3)new WaitForEndOfFrame()作用是,在结束当前帧 摄像机和GUI被渲染以及其它函数完成后才会继续执行当行yield return 后面的代码。 这个我只验证了在LateUpdate执行完之后执行,具体在整个脚本周期中哪个函数执行完之后开始执行还未详细验证。

  (4)new  WaitForFixedUpdate()  作用是,直到当行代码之后第一个FixedUpdate执行之后才会继续执行当行yield return 后面的代码。也就是说,如果是在start里面开启协程的话,第一次执行FixedUpdate之后就会继续执行return后面的代码。

  后面还有许多类型的 返回,没有一一验证,不过作用应该大同小异,即在执行第一个该类型动作之后才会继续执行当行yield return 后面的代码。

  值得一提的是,协程的延迟调用和非阻塞式挂起是用于网络请求等高级结构很好的工具,非常值得花一些时间去仔细研究。

4、停止协程

  协程内停止 可以用yield return break;

  协程外停止 使用 StopCoroutine(string  methodname);

  另外需要注意的是,设置当前协程所在脚本enable为false并不能停止当前协程的执行,只有设置当前脚本挂载gameobject.SetActive(false) 才可以。

 

Guess you like

Origin www.cnblogs.com/unity3ds/p/10993374.html