Unity 中的協同程序



今天咱就說說,協同程序coroutine。(這文章是在網吧敲的,沒有unity,但是所有結論都被跑過,不管你信得過我還是信不過我,都要自己跑一下看看,同時歡迎糾錯)
先說說啥是協程:協同程序是一個非常讓人作嘔的東西,它的表現形式非常像線程,對線程有過接觸的朋友可能更理解我這句話的意思,你沒接觸過線程,那么理解它會有一些難度。但是它不存在線程安全問題,可以放心使用。這不是J哥信口雌黃空口白牙跟這猜的,事實是這樣的:在操作系統層面,也就是更古老的大神們,覺得“並發”是一個很時髦的東西,很好使,於是他們允許操作系統中開啟進程。后來,他們覺得一個進程中,如果也能並發該多好,那么線程應運而生(這些都是身為碼農應該知道的一些常識:一個系統上可以運行多個進程,一個進程可以並發多個線程)。但是由於我們的unity是單線程的,那么還有一句不這么耳熟能詳的話:一個線程可以多協程。於此看來,coroutine可以說是在unity主線程中“並發”的很多協程。這個“並發”為什么加引號,這將是我們研究的重要內容。

介紹了協同的定義,那么可以研究一下它在項目中究竟會怎么用。
下面就是面試考題中可能遇到的幾種協同程序的用法:

1.不使用協同啟動一個返回迭代器的函數。
void 家里來客人()

    沏茶();
     與客人聊天();

IEnumerator 沏茶();

2.在迭代器函數中,yield return 一個協同啟動。 如 

void 家里來客人()

     StartCoroutine(沏茶());
     與客人聊天();


IEnumerator 沏茶()
{
    yield return StartCoroutine(做水());
    找茶葉罐();
}
IEnumerator 做水();
void 找茶葉罐();

3.在迭代器函數中,直接啟動一個協同。如
void 家里來客人()

     StartCoroutine(沏茶());
     與客人聊天();

IEnumerator 沏茶()
{
    StartCoroutine(做水());
    找茶葉罐();
}
IEnumerator 做水();
void 找茶葉罐();

這真的不是讓大伙死記硬背或者是裝逼,我寫的很花哨,是為了讓大伙動手敲一遍驗證一下哈!!!!
下面逐條分析一下把。
對於第一條:這種用法,迭代器“沏茶”,根本不會被並發,比如在這種情況下,雖然沏茶是一個迭代器函數,但是你如果這么執行,也會是沏完了茶(徹底沏完了茶)再跟客人聊天。如果沏茶很費時間,那么不好意思,你在這段時間內,都不會跟客人聊天。這里迭代器等於白費。相當於普通函數。
對於第二條:你在startcoroutine之后,立即開始並發,也就是你一邊執行沏茶,一邊開始跟客人聊天了。現在進來看看你沏茶的時候。在沏茶的協同中,你先yield return 做水。這句話的意思就是,“等待做完水了”,再開始找茶葉罐。值得注意的是,你在做水,找茶葉罐的時候,已經開始跟客人聊天了。
對於第三條:你一遍執行沏茶,一遍與客人聊天。在你沏茶的時候,你是一邊做水,一邊找茶葉罐的。

對於這個例子來看呢。有這么幾條收獲:
1.yield return 跟return 沒有任何關系,yield return xxx 翻譯成人話就是“等待xxx返回之后”,是一個阻塞協同程序的操作。
2.開啟協同程序,實現了偽並發,雖說看起來像並發,但是還是有先后執行次序,所以跟線程有本質的不同——線程理論上來說,先后次序是不可預知的——除非你用信號量等等進行人為控制哈。
3.開啟協同程序,必須得是一個返回迭代的函數。否則編譯不過。但是返回迭代的函數可以不在協同中調用,這樣編譯是通過的,但是基本不會這么寫,代碼不干凈。

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM