日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

对lua协程的一点理解

發布時間:2023/12/10 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对lua协程的一点理解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

讀《Programming In Lua》協程那一章,比較困惑的還是procuer-consumer那個例子:

function consumer(prod)while true dolocal x = receive(prod)print(x)end endfunction receive(prod)local status, value = coroutine.resume(prod)return value endfunction send(x)coroutine.yield(x) -- go back to where resumed endfunction producer()return coroutine.create(function()while true dolocal x = io.read()send(x)endend) end-- consumer-driven design consumer(producer())

producer產生數據,consumer消費數據,producer與consumer都在各自的協程中完成, 代碼很短,但是很難讀 - 至少不是那么一目了然,尤其比起這個直接的循環:

function produce()return io.read() endfunction consume(x)print(x) endwhile true dolocal x = produce()consume(x) end

好在哪里?

書中說可以添加緩存控制速度,或者進行數據過濾 - 但是這在循環版本的producer-consumer中也都能做到,無非在在實現produce是多些邏輯,或者再加個filter的函數處理produce的返回值,協程版本毫無優勢可言。

實在要說其優點,恐怕只是:producer和consumer的代碼在各自的協程中實現,并通過resume-yield交換數據 - 實現了松耦合。這是個優點,可以還是不太滿意,再往下看時,看到了全排列那個例子,稍作修改,讓我比較直觀的感覺到了協程這種控制結構的靈活性:

function send(a)coroutine.yield(a) endfunction receive(prod)local status, value = coroutine.resume(prod)return value endfunction consumer(prod)local function print_result(a)for _, v in ipairs(a) doio.write(v, " ")endio.write('\n')endwhile true dolocal a = receive(prod)if not a then break endprint_result(a)end endfunction producer(a)function permgen(a, n)if n == 0 thensend(a) -- send something for consuming from an recursive callelsefor i=1, n doa[n], a[i] = a[i], a[n]permgen(a, n-1)a[n], a[i] = a[i], a[n]endendendlocal n = table.getn(a)return coroutine.create(function() permgen(a, n) end) endconsumer(producer({1,2,3,4}))

這里全排列采用了遞歸算法:對數組中的每個元素,把它交換到數組末尾,然后對前n-1個元素的子數組做同樣的事,當n==0時,輸出一個排列。

這個在produce的時候,因為在一個遞歸調用中,你無法一個個返回:

  • 要么每找到一個,直接在里面處理 - 這樣produce-consume的結構就有點混淆在一起;
  • 或者先把結果保存在一個共享內存中,產生全部排列后,再逐個處理 - 這樣要另外開辟空間,流程上感覺也不夠簡潔。

于是,協程的有點就顯現出來了,不同于簡單函數中的return,協程可以在找到一個排列后,yield掛起本協程并返回該排列,返回到原來resume這個協程的代碼處,取得數據進行consume,然后繼續resume進入協程獲取排列 - 通過協程靈活控制流程并傳遞數據,十分漂亮。

所以,那個循環版本的問題是:并不是所有produce的數據,都可以簡單的return回來的。

轉載于:https://www.cnblogs.com/baiyanhuang/archive/2012/11/17/2775315.html

總結

以上是生活随笔為你收集整理的对lua协程的一点理解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。