Lua 協同程序(coroutine)

      網友投稿 637 2025-04-01

      什么是協同(coroutine)?


      Lua 協同程序(coroutine)與線程比較類似:擁有獨立的堆棧,獨立的局部變量,獨立的指令指針,同時又與其它協同程序共享全局變量和其它大部分東西。

      協同是非常強大的功能,但是用起來也很復雜。

      線程和協同程序區別

      線程與協同程序的主要區別在于,一個具有多個線程的程序可以同時運行幾個線程,而協同程序卻需要彼此協作的運行。

      在任一指定時刻只有一個協同程序在運行,并且這個正在運行的協同程序只有在明確的被要求掛起的時候才會被掛起。

      協同程序有點類似同步的多線程,在等待同一個線程鎖的幾個線程有點類似協同。

      基本語法

      以下實例演示了以上各個方法的用法:

      coroutine_test.lua 文件

      -- 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

      Lua 協同程序(coroutine)

      )

      coroutine.resume(co2)?--1

      coroutine.resume(co2)?--2

      coroutine.resume(co2)?--3

      print(coroutine.status(co2))???-- suspended

      print(coroutine.running())

      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返回;

      協同程序繼續運行;

      如果使用的協同程序繼續運行完成后繼續調用 resume方法則輸出: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()

      以上實例執行輸出結果為:

      1 2 3 4 5 6 7 8 9 10 11 12 13 ……

      Lua 任務調度

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel表格里怎么查找
      下一篇:Excel中如何設計多個數據表的布局同時顯示多個數據列表(怎么讓excel同時顯示多個表格)
      相關文章
      亚洲国产一区视频| 亚洲成a人片在线播放| 国产亚洲自拍一区| 国产亚洲精品美女久久久久久下载| 亚洲精品456人成在线| 亚洲国产乱码最新视频| 亚洲a级片在线观看| 亚洲国产成人久久三区| 亚洲国产成人手机在线电影bd| 亚洲无人区视频大全| 亚洲日韩乱码久久久久久| 亚洲美女aⅴ久久久91| 亚洲综合一区二区精品久久| 亚洲色大成网站www永久| 亚洲狠狠ady亚洲精品大秀| 亚洲最新在线视频| 亚洲一区二区三区在线| 亚洲成a人片在线观看播放| 亚洲人成在线中文字幕| 亚洲人成7777| 亚洲精品日韩一区二区小说| 亚洲精品无码成人| 亚洲精品tv久久久久| 久久夜色精品国产亚洲av| 亚洲美女又黄又爽在线观看| 国产亚洲一区二区三区在线观看 | 亚洲AV无码国产丝袜在线观看 | 亚洲国产精品久久久久秋霞小| 亚洲大尺度无码无码专线一区| 蜜桃传媒一区二区亚洲AV| 亚洲Av无码国产情品久久 | 亚洲人成影院在线高清| 亚洲 日韩经典 中文字幕| 亚洲av日韩综合一区二区三区| 亚洲成av人在片观看| 亚洲中文字幕无码不卡电影| 亚洲gv猛男gv无码男同短文| 亚洲精品中文字幕无乱码| 中文字幕无码亚洲欧洲日韩| 亚洲?V无码成人精品区日韩| 久久亚洲2019中文字幕|