Luacoroutine不一樣的多線程編程思路是什么

這期內(nèi)容當中小編將會給大家?guī)碛嘘P(guān)Lua coroutine不一樣的多線程編程思路是什么,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

創(chuàng)新互聯(lián)建站是一家專業(yè)提供太倉企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計、做網(wǎng)站、成都h5網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為太倉眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計公司優(yōu)惠進行中。

Lua中的coroutine是一種很好的設(shè)計模式,但我初步的體會還是沒想到其他語言和場合能非常適合用到coroutine的場景。

一、簡介

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

如:

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

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

二、原理探析

  • coroutine創(chuàng)建的所謂的“線程”都不是真正的操作系統(tǒng)的線程,實際上是通過保存stack狀態(tài)來模擬的。

  • 由于是假的線程,所以切換線程的開銷極小,同時創(chuàng)建線程也是輕量級的,new_thread只是在內(nèi)存新建了一個stack用于存放新coroutine的變量,也稱作lua_State

LUA_API lua_State *lua_newthread (lua_State *L)

  • 調(diào)用yield()當前線程交出控制權(quán),同時還可以通過stack返回參數(shù)。調(diào)用resume的線程(可理解為主線程)獲得返回的參數(shù)。

  • Lua yield()和Java中的Thread.yield()有點相似,但是區(qū)別更大。Java中的yield調(diào)用后只是將當前CPU切換到另外一個線程,CPU可能隨時會繼續(xù)回到線程執(zhí)行。

  • 我更傾向于把Lua中的yield()和resume()和Java中的wait()和notify()來對比。它們表現(xiàn)的行為基本一致。

  • 關(guān)于stack實現(xiàn)也可參看Yufeng(Erlang高手)的分析文章 lua coroutine是如何實現(xiàn)的?

三、Why coroutine?

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

  • 每個coroutine有自己私有的stack及局部變量。

  • 同一時間只有一個coroutine在執(zhí)行,無需對全局變量加鎖。

  • 順序可控,完全由程序控制執(zhí)行的順序。而通常的多線程一旦啟動,它的運行時序是沒法預(yù)測的,因此通常會給測試所有的情況帶來困難。所以能用coroutine解決的場合應(yīng)當優(yōu)先使用coroutine。

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

  • Lua是ANSI C實現(xiàn)的,ANSI C并不包含thread的實現(xiàn),因此如果要在Lua增加thread的支持就要使用操作系統(tǒng)本地的實現(xiàn),這樣會造成通用的問題。同時也會使Lua變得臃腫。因此Lua選擇了在ANSI C上實現(xiàn)的coroutine。

  • Lua主要設(shè)計目的之一是給C調(diào)用,如果Lua內(nèi)部又有多線程實現(xiàn)的話會造成C調(diào)用狀態(tài)的混亂,而只提供coroutine層面的掛起則可以保持狀態(tài)的一致性。

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

四、Lua coroutine和Erlang

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

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

五、Lua其他

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

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

  1. 不要存在冗余的關(guān)系,給一個部分負責管理就好。(由Lua/python來管理)

  2. 粘合層(Lua/python接口)不要過胖,我們可以通過引入一個“間接層”來把粘合層做“薄”

雖然Lua的高效和精簡的設(shè)計讓人贊譽有加,但是它的性能排名并不高,和Python大致在同一個級別。另外“膠水語言”的定位也妨礙了它在更多領(lǐng)域的發(fā)展。

上述就是小編為大家分享的Lua coroutine不一樣的多線程編程思路是什么了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)頁名稱:Luacoroutine不一樣的多線程編程思路是什么
網(wǎng)站網(wǎng)址:http://www.muchs.cn/article16/jdocgg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、域名注冊網(wǎng)站改版、響應(yīng)式網(wǎng)站、云服務(wù)器

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計公司