<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # Lua 協同程序(coroutine) ### 什么是協同(coroutine)? Lua 協同程序(coroutine)與線程比較類似:擁有獨立的堆棧,獨立的局部變量,獨立的指令指針,同時又與其它協同程序共享全局變量和其它大部分東西。 協同是非常強大的功能,但是用起來也很復雜。 ### 線程和協同程序區別 線程與協同程序的主要區別在于,一個具有多個線程的程序可以同時運行幾個線程,而協同程序卻需要彼此協作的運行。 在任一指定時刻只有一個協同程序在運行,并且這個正在運行的協同程序只有在明確的被要求掛起的時候才會被掛起。 協同程序有點類似同步的多線程,在等待同一個線程鎖的幾個線程有點類似協同。 ### 基本語法 | 方法 | 描述 | |-----|-----| | coroutine.create() | 創建coroutine,返回coroutine, 參數是一個函數,當和resume配合使用的時候就喚醒函數調用 | | coroutine.resume() | 重啟coroutine,和create配合使用 | | coroutine.yield() | 掛起coroutine,將coroutine設置為掛起狀態,這個和resume配合使用能有很多有用的效果 | | coroutine.status() | 查看coroutine的狀態 注:coroutine的狀態有三種:dead,suspend,running,具體什么時候有這樣的狀態請參考下面的程序 | | coroutine.wrap() | 創建coroutine,返回一個函數,一旦你調用這個函數,就進入coroutine,和create功能重復 | | coroutine.running() | 返回正在跑的coroutine,一個coroutine就是一個線程,當使用running的時候,就是返回一個corouting的線程號 | ### 以下實例演示了以上各個方法的用法: ~~~ ~~~ --?coroutine_test.lua?文件 co?=?coroutine.create( ????function(i) ????????print(i); ????end ) coroutine.resume(co,?1)???--?1 print(coroutine.status(co))??--?dead print("----------") co?=?coroutine.wrap( ????function(i) ????????print(i); ????end ) co(1) print("----------") co2?=?coroutine.create( ????function() ????????for?i=1,10?do ????????????print(i) ????????????if?i?==?3?then ????????????????print(coroutine.status(co2))??--running ????????????????print(coroutine.running())?--thread:XXXXXX ????????????end ????????????coroutine.yield() ????????end ????end ) coroutine.resume(co2)?--1 coroutine.resume(co2)?--2 coroutine.resume(co2)?--3 print(coroutine.status(co2))???--?suspended print(coroutine.running())???--nil print("----------") ~~~ ~~~ 以上實例執行輸出結果為: ~~~ ~~~ 1 dead ---------- 1 ---------- 1 2 3 running thread:?0x7fb801c05868??false suspended thread:?0x7fb801c04c88??true ---------- ~~~ ~~~ coroutine.running就可以看出來,coroutine在底層實現就是一個線程。 當create一個coroutine的時候就是在新線程中注冊了一個事件。 當使用resume觸發事件的時候,create的coroutine函數就被執行了,當遇到yield的時候就代表掛起當前線程,等候再次resume觸發事件。 接下來我們分析一個更詳細的實例: ~~~ ~~~ function?foo?(a) ????print("foo?函數輸出",?a) ????return?coroutine.yield(2?*?a)?--?返回??2*a?的值 end co?=?coroutine.create(function?(a?,?b) ????print("第一次協同程序執行輸出",?a,?b)?--?co-body?1?10 ????local?r?=?foo(a?+?1) ????print("第二次協同程序執行輸出",?r) ????local?r,?s?=?coroutine.yield(a?+?b,?a?-?b)??--?a,b的值為第一次調用協同程序時傳入 ????print("第三次協同程序執行輸出",?r,?s) ????return?b,?"結束協同程序"???????????????????--?b的值為第二次調用協同程序時傳入 end) print("main",?coroutine.resume(co,?1,?10))?--?true,?4 print("--分割線----") print("main",?coroutine.resume(co,?"r"))?--?true?11?-9 print("---分割線---") print("main",?coroutine.resume(co,?"x",?"y"))?--?true?10?end print("---分割線---") print("main",?coroutine.resume(co,?"x",?"y"))?--?cannot?resume?dead?coroutine print("---分割線---") ~~~ ~~~ 以上實例執行輸出結果為: ~~~ ~~~ 第一次協同程序執行輸出?1???10 foo?函數輸出????2 main????true????4 --分割線---- 第二次協同程序執行輸出?r main????true????11??-9 ---分割線--- 第三次協同程序執行輸出?x???y main????true????10??結束協同程序 ---分割線--- main????false???cannot?resume?dead?coroutine ---分割線--- ~~~ ~~~ 以上實例接下如下: - 調用resume,將協同程序喚醒,resume操作成功返回true,否則返回false; - 協同程序運行; - 運行到yield語句; - yield掛起協同程序,第一次resume返回;(注意:此處yield返回,參數是resume的參數) - 第二次resume,再次喚醒協同程序;(注意:此處resume的參數中,除了第一個參數,剩下的參數將作為yield的參數) - yield返回; - 協同程序繼續運行; - 如果使用的協同程序繼續運行完成后繼續調用 resumev方法則輸出:cannot resume dead coroutine resume和yield的配合強大之處在于,resume處于主程中,它將外部狀態(數據)傳入到協同程序內部;而yield則將內部的狀態(數據)返回到主程中。 ### 生產者-消費者問題 現在我就使用Lua的協同程序來完成生產者-消費者這一經典問題。 ~~~ ~~~ local?newProductor function?productor() ?????local?i?=?0 ?????while?true?do ??????????i?=?i?+?1 ??????????send(i)?????--?將生產的物品發送給消費者 ?????end end function?consumer() ?????while?true?do ??????????local?i?=?receive()?????--?從生產者那里得到物品 ??????????print(i) ?????end end function?receive() ?????local?status,?value?=?coroutine.resume(newProductor) ?????return?value end function?send(x) ?????coroutine.yield(x)?????--?x表示需要發送的值,值返回以后,就掛起該協同程序 end --?啟動程序 newProductor?=?coroutine.create(productor) consumer() ~~~ ~~~ ~~~ ~~~ local?newProductor function?productor() ?????local?i?=?0 ?????while?true?do ??????????i?=?i?+?1 ??????????send(i)?????--?將生產的物品發送給消費者 ?????end end function?consumer() ?????while?true?do ??????????local?i?=?receive()?????--?從生產者那里得到物品 ??????????print(i) ?????end end function?receive() ?????local?status,?value?=?coroutine.resume(newProductor) ?????return?value end function?send(x) ?????coroutine.yield(x)?????--?x表示需要發送的值,值返回以后,就掛起該協同程序 end --?啟動程序 newProductor?=?coroutine.create(productor) consumer() ~~~ ~~~ 以上實例執行輸出結果為: ~~~ ~~~ 1 2 3 4 5 6 7 8 9 10 11 12 13 …… ~~~ ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看