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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Lua coroutine 不一样的多线程编程思路

發(fā)布時(shí)間:2025/5/22 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Lua coroutine 不一样的多线程编程思路 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

上周末開(kāi)始看《Lua程序設(shè)計(jì)》第二版,目前體會(huì)到其中比較有趣的有兩點(diǎn),一是強(qiáng)大的table數(shù)據(jù)結(jié)構(gòu),另外就是coroutine。也許Lua中的coroutine是一種很好的設(shè)計(jì)模式,但我初步的體會(huì)還是沒(méi)想到其他語(yǔ)言和場(chǎng)合能非常適合用到coroutine的場(chǎng)景。

一、簡(jiǎn)介

協(xié)同程序與線(xiàn)程差不多,也就是一條執(zhí)行序列,擁有自己獨(dú)立的棧,局部變量和指令指針,同時(shí)又與其它協(xié)同程序共享全局變量和其它大部分東西。線(xiàn)程與協(xié)同程序的主要區(qū)別在于,一個(gè)具有多線(xiàn)程的程序可以同時(shí)運(yùn)行幾個(gè)線(xiàn)程,而協(xié)同程序卻需要彼此協(xié)作地運(yùn)行。就是說(shuō),一個(gè)具有多個(gè)協(xié)同程序的程序在任何時(shí)刻只能運(yùn)行一個(gè)協(xié)同程序,并且正在運(yùn)行的協(xié)同程序只會(huì)在其顯示地掛起時(shí),它的執(zhí)行才會(huì)暫停。

如:

co = coroutine.create(function () for i=1,10 do print("co", i) coroutine.yield() end end)

從主線(xiàn)程調(diào)用
coroutine.resume(co)
會(huì)依次打印1到10

二、原理探析

  • coroutine創(chuàng)建的所謂的“線(xiàn)程”都不是真正的操作系統(tǒng)的線(xiàn)程,實(shí)際上是通過(guò)保存stack狀態(tài)來(lái)模擬的。
  • 由于是假的線(xiàn)程,所以切換線(xiàn)程的開(kāi)銷(xiāo)極小,同時(shí)創(chuàng)建線(xiàn)程也是輕量級(jí)的,new_thread只是在內(nèi)存新建了一個(gè)stack用于存放新coroutine的變量,也稱(chēng)作lua_State

LUA_API lua_State *lua_newthread (lua_State *L)

  • 調(diào)用yield()當(dāng)前線(xiàn)程交出控制權(quán),同時(shí)還可以通過(guò)stack返回參數(shù)。調(diào)用resume的線(xiàn)程(可理解為主線(xiàn)程)獲得返回的參數(shù)。
  • Lua yield()和Java中的Thread.yield()有點(diǎn)相似,但是區(qū)別更大。Java中的yield調(diào)用后只是將當(dāng)前CPU切換到另外一個(gè)線(xiàn)程,CPU可能隨時(shí)會(huì)繼續(xù)回到線(xiàn)程執(zhí)行。
  • 我更傾向于把Lua中的yield()和resume()和Java中的wait()和notify()來(lái)對(duì)比。它們表現(xiàn)的行為基本一致。
  • 關(guān)于stack實(shí)現(xiàn)也可參看Yufeng(Erlang高手)的分析文章 lua coroutine是如何實(shí)現(xiàn)的?

三、Why coroutine?

上面對(duì)coroutine有個(gè)基本的了解,因此大家都會(huì)象我一樣去想,為什么要用coroutine?先研究下優(yōu)點(diǎn)

  • 每個(gè)coroutine有自己私有的stack及局部變量。
  • 同一時(shí)間只有一個(gè)coroutine在執(zhí)行,無(wú)需對(duì)全局變量加鎖。
  • 順序可控,完全由程序控制執(zhí)行的順序。而通常的多線(xiàn)程一旦啟動(dòng),它的運(yùn)行時(shí)序是沒(méi)法預(yù)測(cè)的,因此通常會(huì)給測(cè)試所有的情況帶來(lái)困難。所以能用coroutine解決的場(chǎng)合應(yīng)當(dāng)優(yōu)先使用coroutine。

再看缺點(diǎn),研究coroutine缺點(diǎn)之前,我尋找了一下Lua中為什么實(shí)現(xiàn)coroutine的一些說(shuō)明。在巴西人寫(xiě)的paper Coroutines in Lua(pdf)中解釋了幾個(gè)原因:

  • Lua是ANSI C實(shí)現(xiàn)的,ANSI C并不包含thread的實(shí)現(xiàn),因此如果要在Lua增加thread的支持就要使用操作系統(tǒng)本地的實(shí)現(xiàn),這樣會(huì)造成通用的問(wèn)題。同時(shí)也會(huì)使Lua變得臃腫。因此Lua選擇了在ANSI C上實(shí)現(xiàn)的coroutine。
  • Lua主要設(shè)計(jì)目的之一是給C調(diào)用,如果Lua內(nèi)部又有多線(xiàn)程實(shí)現(xiàn)的話(huà)會(huì)造成C調(diào)用狀態(tài)的混亂,而只提供coroutine層面的掛起則可以保持狀態(tài)的一致性。

以上這些理由都是基于Lua特殊的原因而使用的,并不是很通用的原因。我們也了解到,coroutine實(shí)際上是一種古老的設(shè)計(jì)模式,它在60年代就已經(jīng)定型,但是現(xiàn)代語(yǔ)言很少有重視這個(gè)特性,目前可以舉例的有Windows的fibers, Python的generators

四、Lua coroutine和Erlang

上面優(yōu)點(diǎn)有1條沒(méi)展開(kāi),就是每個(gè)coroutine有自己私有的stack及內(nèi)存變量空間。因此可以認(rèn)為coroutine和Erlang中的process是非常相似的。但是coroutine只能同時(shí)只有一個(gè)在執(zhí)行,如果能讓他多個(gè)同時(shí)跑,我覺(jué)得就和Erlang非常相似了。

《Lua程序設(shè)計(jì)》第二版30.2介紹的一種實(shí)現(xiàn)方法,讓多個(gè)c threads啟動(dòng),然后每個(gè)c thread啟動(dòng)一個(gè)coroutine(類(lèi)似Erlang process),然后通過(guò)stack傳遞變量值(類(lèi)似Erlang process message),這樣就可以實(shí)現(xiàn)一個(gè)類(lèi)似Erlang的process模型了。由于coroutine實(shí)際上可以用任何語(yǔ)言實(shí)現(xiàn),那其他語(yǔ)言應(yīng)該也可實(shí)現(xiàn)同樣這種設(shè)計(jì)方法。

五、Lua其他

Lua目前主要用在游戲編程領(lǐng)域,通常的觀點(diǎn)Lua是“膠水語(yǔ)言”。用來(lái)把各個(gè)模塊化的功能粘合起來(lái)。就我目前閱讀的一些代碼來(lái)看,C和Lua通常是混合在一起的,并沒(méi)有明確的邊界。對(duì)于我一個(gè)外行的眼光看來(lái)我分不清哪些是在做C的事情,哪些是在調(diào)用Lua。特別是這個(gè)“膠水”如果放得太多,系統(tǒng)中各個(gè)模塊的獨(dú)立性將會(huì)受到影響。比如云風(fēng)的這篇Lua 不是 C++也提到,“這屬于過(guò)厚的粘合層,是絕對(duì)需要拋棄的”。

另外Code@Pig一篇[網(wǎng)游設(shè)計(jì)] 一點(diǎn)感想也提到要簡(jiǎn)化調(diào)用,我總結(jié)它的觀點(diǎn)主要兩點(diǎn):

  • 不要存在冗余的關(guān)系,給一個(gè)部分負(fù)責(zé)管理就好。(由Lua/python來(lái)管理)
  • 粘合層(Lua/python接口)不要過(guò)胖,我們可以通過(guò)引入一個(gè)“間接層”來(lái)把粘合層做“薄”
  • 雖然Lua的高效和精簡(jiǎn)的設(shè)計(jì)讓人贊譽(yù)有加,但是它的性能排名并不高,和Python大致在同一個(gè)級(jí)別。另外“膠水語(yǔ)言”的定位也妨礙了它在更多領(lǐng)域的發(fā)展。

    轉(zhuǎn)載于:https://blog.51cto.com/timyang/307675

    《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專(zhuān)家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的Lua coroutine 不一样的多线程编程思路的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。