Unity3D 中的協(xié)同程序Coroutine

今天咱就說說協(xié)同程序coroutine。

什么是協(xié)同程序

先說說啥是協(xié)程:它的表現(xiàn)形式非常像線程,對線程有過接觸的朋友可能更理解我這句話的意思,你沒接觸過線程,那么理解它會有一些難度。但是它不存在線程安全問題,可以放心使用。
是這樣的:在操作系統(tǒng)層面,也就是更古老的大神們,覺得“并發(fā)”是一個很時髦的東西,很好使,于是他們允許操作系統(tǒng)中開啟進程。后來,他們覺得一個進程中,如果也能并發(fā)該多好,那么線程應運而生(這些都是身為碼農(nóng)應該知道的一些常識:一個系統(tǒng)上可以運行多個進程,一個進程可以并發(fā)多個線程)。
但是由于我們的unity是單線程的,那么還有一句不這么耳熟能詳?shù)脑挘阂粋€線程可以多協(xié)程。于此看來,coroutine可以說是在unity主線程中“并發(fā)”的很多協(xié)程。這個“并發(fā)”為什么加引號,這將是我們研究的重要內(nèi)容。介紹了協(xié)同的定義,那么可以研究一下它在項目中究竟會怎么用。下面就是面試考題中可能遇到的幾種協(xié)同程序的用法:

1.不使用協(xié)同啟動一個返回迭代器的函數(shù)。

void 家里來客人()
    {    
          沏茶();
          與客人聊天();
    }
    IEnumerator 沏茶();

2.在迭代器函數(shù)中,yield return 一個協(xié)同啟動。 如

void 家里來客人()
{
     StartCoroutine(沏茶());
     與客人聊天();
}
IEnumerator 沏茶()
{
    yield return StartCoroutine(做水());
    找茶葉罐();
}
IEnumerator 做水();
void 找茶葉罐();

3.在迭代器函數(shù)中,直接啟動一個協(xié)同。如

void 家里來客人()
{
     StartCoroutine(沏茶());
     與客人聊天();
}
IEnumerator 沏茶()
{
    StartCoroutine(做水());
    找茶葉罐();
}
IEnumerator 做水();
void 找茶葉罐();

下面逐條分析一下把。

  • 對于第一條:這種用法,迭代器“沏茶”,根本不會被并發(fā),比如在這種情況下,雖然沏茶是一個迭代器函數(shù),但是你如果這么執(zhí)行,也會是沏完了茶(徹底沏完了茶)再跟客人聊天。如果沏茶很費時間,那么不好意思,你在這段時間內(nèi),都不會跟客人聊天。這里迭代器等于白費。相當于普通函數(shù)。
  • 對于第二條:你在startcoroutine之后,立即開始并發(fā),也就是你一邊執(zhí)行沏茶,一邊開始跟客人聊天了?,F(xiàn)在進來看看你沏茶的時候。在沏茶的協(xié)同中,你先yield return 做水。這句話的意思就是,“等待做完水了”,再開始找茶葉罐。值得注意的是,你在做水,找茶葉罐的時候,已經(jīng)開始跟客人聊天了。
  • 對于第三條:你一遍執(zhí)行沏茶,一遍與客人聊天。在你沏茶的時候,你是一邊做水,一邊找茶葉罐的。

對于這個例子來看呢。有這么幾條收獲:

  1. yield return 跟return 沒有任何關(guān)系,yield return xxx 翻譯成人話就是“等待xxx返回之后”,是一個阻塞協(xié)同程序的操作。
  2. 開啟協(xié)同程序,實現(xiàn)了偽并發(fā),雖說看起來像并發(fā),但是還是有先后執(zhí)行次序,所以跟線程有本質(zhì)的不同——線程理論上來說,先后次序是不可預知的——除非你用信號量等等進行人為控制哈。
  3. 開啟協(xié)同程序,必須得是一個返回迭代的函數(shù)。否則編譯不過。但是返回迭代的函數(shù)可以不在協(xié)同中調(diào)用,這樣編譯是通過的,但是基本不會這么寫,代碼不干凈。

主要的骨頭已經(jīng)啃了,剩下一個就是協(xié)同程序什么時候才算完結(jié)?

  1. 碰見yield break——直接跳出攜程,對某些判定失敗必須跳出的時候,比如加載AssetBundle的時候,WWW都失敗了,后邊加載bundle沒有必要了,這時候可以yield break。這個語句非常有用。
  2. 執(zhí)行到最后一行——最后一行不一定非得是 yield return xxx;我經(jīng)常最后一句是一個 excute delegate什么的。
  3. 補充:yield return null;yield return 0; 均不算完結(jié)協(xié)同程序?。。?!

弄懂了這些,自己去揣摩揣摩,就能搞定協(xié)同啦。難點就是這些。它雖然惡心,但是并不難,希望對大家有幫助!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容