成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

淺析Lua下實現搶占式多線程

移動開發 iOS
淺析Lua下實現搶占式多線程是本文要介紹的內容,主要是來學習lua的多線程,關于線程的問題,我們來看本文詳解。

淺析Lua下實現搶占式多線程是本文要介紹的內容,主要是來學習lua多線程。Lua 5.2 的開發進度可以回溯到 2010 年 1 月。漫長的流程到今天已經快兩年過去,終于等到了 beta 版。我十分期待它可以在 2011 年內正式發布。在這幾經折騰的兩年里,許多新特性企圖擠進 5.2 版,又最終被否決。

當我們審視改進列表,似乎看不到太多耳目一新的東西。但如果仔細閱讀一下源代碼,就會發現,大部分地方都重新實現過了,以配合這些表面上看起來不大的修改。如果你對 Lua 有足夠理解,會發現,這次最激動人心的改進是 "yieldable pcall and metamethods" 。官方也把之列為 Main changes 第一條。語言上的重大新特性 goto 卻被列在末尾。

當然,這只是我粗淺的理解而已。沒有經過實踐使用 5.2 一段時間,下這樣的論斷有點太草率。不過我還是想談談,這點改進可以給我們的開發帶來什么。

coroutine 的 yield 現在幾乎可以在任何地方使用了。我用了幾乎,是因為它依然有一些限制。這些限制不大容易說的很清楚,為了理解其限制,我花了一整天實現閱讀 lua 5.2 beta 版的源代碼。這個話題下次有機會我再另寫一篇 blog 總結一下。今天只談應用。

我們知道 coroutine 可以實現一個協同多線程模型。即,每個線程(coroutine) 只在用戶期望的地方跳出來,并可以在以后跳回去(保持當初跳離的狀態)。這解決了許多搶占式多線程的麻煩。lua 的發明人在一篇訪談中談到了 coroutine 解決并發的問題。

但是,讓用戶不厭其煩的寫 yield 是件很討厭的事情。往往框架會把 yield 調用藏起來。如果我沒記錯,我讀過的早期的 kepler 框架就是把 yield 藏在 html 的輸出里的。能夠想到的更漂亮的做法是編寫一個 lua debug hook ,在 hook 里調用 yield 。這樣就可以讓 lua vm 每跑幾行 lua byte code 就自動做 yield 一次。

可惜的是,lua 5.1 以前的版本不支持這個。因為 yield 限制太多了。如果恰巧 yield 發生在一次 metamethod 調用內部,或 pcall 內部,就會失敗。這和 C/Lua 函數嵌套有關。lua vm 在實現 pcall 及 metamethod 機制時,不斷的在 C 函數以及 lua 函數間跳轉。

一旦 yield 發生在多層 C 函數與 lua 函數嵌套調用的內部。用 longjmp 返回的 yield 機制,會丟失 C 函數調用的 stack frame 。也就是說,lua vm 本身的狀態可以保留在 L 中,但 C 函數的狀態卻丟失了,無法正確返回。Lua 5.2 為了解決這個問題,引入了新的 api ,有興趣可以閱讀新的文檔的 4.7 – Handling Yields in C 。不過真的想全部搞清楚,還是推薦閱讀一下源代碼。

只使用系統自帶的 debug 庫是不夠的。用 lua 的 debug.sethook 設置一個 lua 函數做 hook ,里面依然不能調用 coroutine.yield 。這還是受到了 lua 實現的限制。正確的方法是直接使用 C api lua_sethook,把這樣一個 hook 函數設進去:

  1. static void  
  2.  
  3. hook(lua_State *L, lua_Debug *ar)  
  4. {  
  5.     lua_yield(L,0);  

至于你想讓它每隔幾行 lua 代碼 yield 一次,還是讓它發生在函數調用的時候,這看你的喜好。但一旦設置成功,一段 lua 代碼就可以透明的定期 yield 出來了。

這些有什么用?我設想了兩種用法,

一、是用 lua 做一個調度器,模擬出一個搶占式的多線程庫。本質上,這個庫是基于 coroutine 實現的。但切換線程是利用的 debug hook 定期強制切換?;谶@個庫,可以把以前我寫過的這個小玩意改進一下。做的更易用一些。

二、是在一個 os 進程內啟動多個獨立的 lua state ,每個 lua state 并不包含多個 coroutine ,而只用一個 main thread 。設置 debug hook ,讓 main thread 可以每跑一個階段就 yield 出來,把控制權交還到上層的 C 代碼。在 C 層次寫一個有效的調度器。對 lua state 來說,每個都是獨立的,它們之間可以通過 zeromq 這樣的庫通訊。lua state 還可以部署到多個 os thread 上,實現一個 M:N 的線程模型。它的調度器會比 os 來的更為高效。(關于在語言級實現 M:N 線程模型和 OS 級實現 M:N 線程序模型的性能差異,上個月 7 月 12 日我們在 google+ 上做過一次討論??上窃谟邢奕ψ永镒龅模瑫簳r沒找到方法公開)且少占用大量的堆棧資源。

話說到這里,再看看,其實這不就是 Erlang 的模型么?:)

ps. 其實 lua 的早期版本也可以通過 lua coco 實現無限制的 yield 操作。但 coco 使用了 OS 的 fiber 庫 這比 5.2 版的 lua 實現多出了額外的堆棧開銷。

一些還沒實現的想法:游戲服務器里的 npc ai 等東西是不是可以放在一個個獨立的 lua state 中完成?它們相互不影響,用消息交互。可以一開始分配好一個 state 池,用來動態綁定新的 AI 單位(減少啟動初始化的代價)。把任務切分成獨立的小單位,在獨立的 lua state 中做,我想對 lua 的 gc 操作也是極為有利的。

小結:淺析Lua下實現搶占式多線程的內容介紹完了,希望通過本文的學習能對你有所幫助!

責任編輯:zhaolei 來源: 互聯網
相關推薦

2010-02-01 17:25:09

Python多線程

2009-08-12 18:04:44

編寫C#多線程

2010-03-03 17:44:07

Python多線程

2011-04-08 10:36:38

MFC多線程

2009-07-03 17:18:34

Servlet多線程

2009-07-17 17:29:13

多任務多線程

2011-06-24 11:12:39

Qt 多線程 線程

2011-08-31 16:22:51

LUA多線程

2011-06-24 11:03:31

Qt 多線程 線程

2009-04-27 13:15:04

多線程方法run()

2011-08-31 16:30:19

Lua多線程

2011-04-13 14:53:32

2009-08-21 11:31:59

異步和多線程的區別

2009-08-28 15:57:56

C#線程傳遞參數

2014-08-13 10:41:08

linux線程

2009-08-27 14:29:28

顯式實現接口

2009-09-14 19:21:36

Javascript透

2020-03-31 08:05:23

分布式開發技術

2023-10-19 08:30:58

線程源碼thread

2011-10-31 15:59:56

SQLiteiPhoneiOS
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品国产第一综合99久久 | 日韩免费1区二区电影 | 伊人免费视频二 | 日韩在线免费视频 | 亚洲黄色一级 | 成年免费大片黄在线观看一级 | 在线观看国产 | 日韩成人在线播放 | 免费一区二区三区 | 成人国产精品久久久 | 男人天堂社区 | 一级毛片播放 | www.一区二区三区 | 噜啊噜在线 | 日韩一级免费电影 | 精品1区| 久久看片 | 亚洲国产成人av好男人在线观看 | 亚洲精品久久久一区二区三区 | 久久精品视频9 | 二区视频 | 老司机67194精品线观看 | 日韩和的一区二区 | 亚洲精品一区在线观看 | 香蕉久久a毛片 | 精品一级 | 日韩在线一区二区 | 久久久www成人免费无遮挡大片 | 在线免费观看成人 | 亚州综合在线 | 欧美一级片在线观看 | 日韩午夜影院 | 伊人久久伊人 | 四虎永久在线精品免费一区二 | 天堂三级 | 一区二区三区播放 | 日韩国产中文字幕 | 男人阁久久 | 国产精品国产精品国产专区不片 | 亚洲欧美日韩精品久久亚洲区 | 日韩欧美二区 |