A coroutine is a function that is executed partially and, presuming suitable conditions are met, will be resumed at some point in the future until its work is done. → 協程是一個部分執行, 遇到條件 (yield return
) 會掛起, 直到條件知足纔會被喚醒繼續執行後面代碼的一種函數.html
協程的做用一共有兩點 :編程
1. 延時等待一段時間執行代碼 2. 等某個操做完成以後再執行後面的代碼
總而言之, 協程控制了代碼在特定的時機執行, 是對單線程控制權的交替.數據結構
Coroutines 不是多線程, 不是異步技術, 協程都在 MainThread 中執行, 並且每一個時刻只有一個 Coroutine 在執行. Coroutine 是一個 function, 能夠部分執行, 當條件知足時, 將來會被再次執行直到整個函數執行完畢.多線程
協程可以把一個計算或操做,分解成若干步,而且能夠在任何一步停下來,並在須要的時候繼續執行剩下的步驟。這樣的模型給予了更細粒度的控制一個操做或是功能, 好比, 一個很是耗時間的操做, 被分步執行能夠更好的控制程序響應. 好比, 一個操做須要依賴各類條件, 能夠更好的處理條件不知足的時候的狀況. 也可以更好的把操做或是計算過程當中的狀態變化, 與其餘的狀態變化交互, 然而, 程序運行的過程就是抽象數據結構和結構不斷變化的過程, 協程可以優雅天然的進行這個變化過程的需求.併發
Unity 在每一幀都會去處理 GameObject 裏帶有的 Coroutine Function, 直到 Coroutine Function 被執行完畢. 當一個 Coroutine 開始啓動時, 它會執行到遇到 yield 爲止, 遇到 yield 的時候 Coroutine 會暫停執行, 直到知足 yield 語句的條件, 會開始執行 yield 語句後面的內容, 直到遇到下一個 yield 爲止 ... 如此循環直到整個函數結束, 這就是能夠將一個函數分割到多個幀裏去執行的思想.異步
也就是說, Coroutines 最棒的就是函數的執行能夠不在一次 Frame 裏完成, 能夠在多個 Frame 中完成. 好比, 咱們但願看到物體透明度的改變, 若是讓 color.a 的變化在一幀內完成, 那麼咱們是看不出來這其中的變化得, 由於太快, 因此讓 color.a 的變化必須在多個幀內完成, 咱們纔有可能用肉眼看到這一變化的過程.函數
Unity 的協程系統基於 C# 的接口 : IEnumerator, 容許爲本身的集合類型編寫枚舉類.ui
歷史上先有的協程, 是操做系統用來模擬多任務併發, 協程是非搶佔式的, 多任務時間片不能公平分享, 線程是搶佔式的;url
線程能利用多核達到真正的並行計算, 若是任務設計的好, 線程能幾乎成倍的提升你的計算能力, 可是線程的缺點也很明顯, 那就是沒有設計好致使大量的鎖 | 切換 | 等待, 這些不少都是應用層的問題. 而協程由於是非搶佔式, 因此須要用戶本身釋放使用權來切換到其餘協程, 所以同一時間其實只有一個協程擁有運行權, 至關於單線程的能力.操作系統
協程相對線程的最大優勢就是 : 讓原來要使用異步 + 回調方式寫的非人類代碼, 能夠用看似同步的方式寫出來.
- 協程是 C# 線程的替代品, 是 Unity 不使用線程的解決方案. 可是, 協程不是線程, 不能進行異步執行, 協程和 MonoBehaviour 的 Update 函數同樣也是在 MainThread 中執行的. - 使用協程不用考慮同步和鎖的問題. - 在程序中調用 StopCoroutine() 方法只能終止以字符串形式啓動(開始)的協程; - 多個協程能夠同時運行,它們會根據各自的啓動順序來更新; - 協程能夠嵌套任意多層; - 若是你想讓多個腳本訪問一個協程,那麼你能夠定義靜態的協程; - 協程不是多線程(儘管它們看上去是這樣的),它們運行在同一線程中,跟普通的腳本同樣; - 若是你的程序須要進行大量的計算,那麼能夠考慮在一個隨着時間進行的協程中處理它們; - IEnumerator 類型的方法不能帶 ref 或者 out 型的參數,但能夠帶被傳遞的引用; - 目前在 Unity 中沒有簡便的方法來檢測做用於對象的協程數量以及具體是哪些協程做用在對象上。 - 協程能夠減小 callback 的使用, 可是不能徹底替換 callback. 基於事件驅動的編程裏面反而不能發揮協程的做用, 而用 callback 更適合. 想象一下用協程來寫 GUI 的事件處理你怎麼寫, 計算密集型的異步代碼裏面也只能用 callback. 而 NodeJs 那種 io 瓶頸單任務流程用協程的確很適合, 可是也須要 callback 做補充. - 狀態機用協程其實也有問題, 好比狀態裏面嵌套子狀態, 再由子狀態切換到其餘狀態的子狀態, 開銷和代碼都會變差, 反而不如經典的狀態機簡單明瞭高效.
Book <<Unity Case Study Manual>>
http://blog.csdn.net/u010153703/article/details/38557237
http://blog.csdn.net/huang9012/article/details/38492937
https://www.zhihu.com/question/20511233?rf=23290260
https://www.zhihu.com/question/20511233
End.