IEnumerator里的迭代器和可迭代的错误理解

IEnumerator里的迭代器和可迭代的错误理解

看起来像枚举,但实际上它的意思是C#中的迭代器(IEnumerator)和可迭代器(IEnumerable)。 误会就不详细说了。

迭代模式(指设计模式):允许访问数据项序列中的所有元素,而不用关心序列的类型(数组、列表、链表等)。

看一下yield return实现的迭代器代码:

公共 IEnumerator GetEnumerator()

for (int 索引 = 0; 索引 < 值.长度; 索引 ++)

产量返回值[(索引+起始点)%值.长度];

yield return 语句仅意味着“暂时”退出该方法 - 事实上unity 协程和线程区别,您可以将其视为暂停。

了解这些可以帮助你更好地理解unity中的协程。

说到协程,我们首先回顾一下线程和进程的以下概念。 在操作系统(os)层面unity 协程和线程区别,有两个我们看不到但实际存在的“东西”,进程和线程。 这两个东西是用来模拟“并行性”的。 编写操作系统程序员使用某些策略将CPU计算资源分配给不同的进程和线程,使用户“认为”有几个不同的事情“同时”发生。 在单个CPU上,是os代码强制一个进程或线程挂起并被另一个进程代替进行计算,所以它实际上是串行的,但“概念上是并行的”。 在当今的多核 CPU 上,线程可能是“真正并行的”。

1 线程、进程和协程的区别

进程有自己独立的堆和栈。 它既不共享堆也不共享堆栈。 该进程由操作系统调度。

线程有自己独立的栈和共享堆。 堆是共享的,但栈是不共享的。 线程也由操作系统调度(标准线程是)。

协程与线程共享相同的堆,但不共享堆栈。 协程由程序员在协程代码中显式调度。

一个应用程序一般对应一个进程。 一个进程一般有一个主线程和多个辅助线程。 线程并行运行。 可以在线程中启用协程,以允许程序在特定时间内运行。

协程和线程的区别在于,协程避免了无意义的调度,这可以提高性能。 然而3D场景,程序员必须承担自己调度的责任。 同时,协程也失去了标准线程使用多个CPU的能力。 。

例如,假设有一个单核操作系统。 系统上没有需要运行的其他程序。 有两个线程A和B。单独运行时,A和B都需要10秒才能完成任务。 而且任务都是计算操作,AB之间不存在竞争和数据共享的问题。 既然两个线程AB是并行的,那么操作系统就会不断地在两个线程AB之间进行切换,以达到伪并行的效果。 假设切换频率为每秒一次,则切换成本为0.1秒(主要是堆栈切换),总共耗时20+19*0.1=21.9秒。 如果使用协程方式,可以先运行协程A。 当A结束后,就会让给协程B,只发生一次切换,总时间为20+1*0.1=20.1秒。 如果系统是双核,线程是标准线程,那么两个线程AB可以真正并行,总时间只需要10秒,而协程方案仍然需要20.1秒。

Unity协程执行原理

unity中协程执行过程中音乐音效,通过yield return XXX暂停程序,执行接下来的内容。 请注意,协程不是线程。 在遇到yield return XXX语句之前,协程方法和一般方法是一样的,即程序执行完yield return XXX语句后,接下来会执行StartCoroutine()方法之后的程序。 还是单线程模式,只有yield return XXX语句之后的内容暂时挂起。 等到特定时间执行。

所以被挂起的程序什么时候会被执行取决于monoBehavior的生命周期。

也就是说,协程主要在 update() 方法之后、lateUpdate() 方法之前调用。 接下来我们通过一个小例子来理解一下。

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("AAAAAAAAAAAAAAAAA" + i);
            Thread.Sleep(10);
        }
    }
    IEnumerator tt()
    {
        for (int i = 0; i < 100; i++) //循环B
        {
            Debug.Log("BBBBBBBBBBBBBBBBBBBB" + i);
        }
        yield return new WaitForSeconds(1); //协程1
        for (int i = 0; i < 100; i++) //循环C
        {
            Debug.Log("CCCCCCCCCCCCCCCCCCCCC" + i);
            yield return null; //协程1
        }
    }
    // 更新数据
    void Update()
    {
        Debug.Log("--------Update");
    }
    //晚于更新
    void LateUpdate()
    {
        Debug.Log("------LateUpdate");
    }
}

程序运行结果为:

B===》A===》重复一秒(更新===》LateUpdate)然后===》循环(更新===》C===》LateUpdate)

文章来源:https://blog.csdn.net/qq_35647121/article/details/95105476