溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2021-10-21 10:41:30 來源:億速云 閱讀:168 作者:柒染 欄目:大數據

這期內容當中小編將會給大家帶來有關Lua coroutine不一樣的多線程編程思路是什么,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

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

一、簡介

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

如:

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

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

二、原理探析

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

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

LUA_API lua_State *lua_newthread (lua_State *L)

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

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

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

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

三、Why coroutine?

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

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

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

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

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

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

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

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

四、Lua coroutine和Erlang

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

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

五、Lua其他

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

另外Code@Pig一篇[網游設計] 一點感想也提到要簡化調用,我總結它的觀點主要兩點:

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

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

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

上述就是小編為大家分享的Lua coroutine不一樣的多線程編程思路是什么了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女