golua虛擬機(jī)的使用分析,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

創(chuàng)新互聯(lián)公司專業(yè)IDC數(shù)據(jù)服務(wù)器托管提供商,專業(yè)提供成都服務(wù)器托管,服務(wù)器租用,成都棕樹電信機(jī)房,成都棕樹電信機(jī)房,成都多線服務(wù)器托管等服務(wù)器托管服務(wù)。
之前一直想把openflow這樣的分布式流程系統(tǒng)做起來(lái),但是時(shí)間和應(yīng)用場(chǎng)景的問(wèn)題所以都是做了一個(gè)半拉子工程,而且之前想的也有點(diǎn)簡(jiǎn)單了,認(rèn)為只要有同學(xué)愿意,在開發(fā)上應(yīng)該沒(méi)問(wèn)題,但是最終還是出現(xiàn)了項(xiàng)目管理和開發(fā)能力的問(wèn)題,最終擱淺了。但是我想做一個(gè)分布式流程調(diào)度系統(tǒng)的想法一直沒(méi)有斷,其實(shí)在公司內(nèi)和另外一個(gè)同學(xué)做過(guò)一個(gè)flow系統(tǒng),也在線上使用了,直到現(xiàn)在還在使用。前一段時(shí)間就想把這個(gè)系統(tǒng)再優(yōu)化梳理一下,目標(biāo)是做一個(gè)小巧的開源可用版本。經(jīng)過(guò)一段時(shí)間的梳理目前已經(jīng)初步完成了,后臺(tái)+前端代碼的重新梳理也已經(jīng)完成了。
而今天主要想寫的是其中使用到的一個(gè)技術(shù)點(diǎn):lua。內(nèi)部版本我們使用的是golang開發(fā),但是在執(zhí)行中為了保證流程之間不會(huì)互相影響,我們使用lua虛擬機(jī)技術(shù);讓每個(gè)流程在執(zhí)行的時(shí)候在一個(gè)獨(dú)立的lua虛擬機(jī)中執(zhí)行。內(nèi)部版本使用golua這個(gè)組件,但是這個(gè)組件有個(gè)問(wèn)題,它其實(shí)是一個(gè)cgo的版本,就是它其實(shí)上是調(diào)用本地lua庫(kù)來(lái)執(zhí)行,所在在編譯部署和執(zhí)行上都有一定的效率問(wèn)題。
所以在新開發(fā)的版本上我想使用其它的方式,在研究了一段時(shí)間后決定使用gopher-lua這個(gè)組件,這個(gè)是使用golang重寫的支持Lua5.1的虛擬機(jī),在執(zhí)行上可以直接golang無(wú)縫結(jié)合,有非常好的go的api接口,在使用上也流暢很多,在實(shí)現(xiàn)思路上也采用golang的一些思路,和golang結(jié)合更好。也通過(guò)這次學(xué)習(xí)了一把lua,才發(fā)現(xiàn)這個(gè)技術(shù)確實(shí)很牛,據(jù)統(tǒng)計(jì)lua的c實(shí)現(xiàn)代碼才1w行左右,但是執(zhí)行非常高效,而且lua的預(yù)留關(guān)鍵字也非常少。可以說(shuō)是一個(gè)非常簡(jiǎn)潔又高效的語(yǔ)言。
在我這個(gè)flow項(xiàng)目非常合適,所以用gopher-lua替換了golua,因?yàn)間opher-lua的api和類型支持比golua要好很多,所以在替換后精簡(jiǎn)了不少代碼。下面就介紹一下項(xiàng)目中使用到的一些關(guān)鍵點(diǎn)。
在使用上api非常簡(jiǎn)單,主要有以下幾步:
引入gopher-lua
創(chuàng)建虛擬機(jī)
使用虛擬機(jī)執(zhí)行l(wèi)ua語(yǔ)句或lua腳本文件
關(guān)閉虛擬機(jī)
package mainimport lua "github.com/yuin/gopher-lua" // 1.引入gopher-luafunc main() {
L := lua.NewState() // 2.創(chuàng)建一個(gè)lua解釋器實(shí)例defer L.Close() // 4.關(guān)閉虛擬機(jī)if err := L.DoString(`print("hello")`); err != nil { // 3.用創(chuàng)建的虛擬機(jī)來(lái)執(zhí)行l(wèi)ua語(yǔ)句
// if err := L.DoFile("hello.lua"); err != nil { // 3.用創(chuàng)建的虛擬機(jī)來(lái)執(zhí)行l(wèi)ua腳本文件panic(err)
}
}api在使用上還是非常簡(jiǎn)單的。其它關(guān)于基本數(shù)據(jù)類型的這里就不多介紹了,在其github站點(diǎn)上有非常詳細(xì)的介紹。
下面將主要介紹2個(gè)在flow項(xiàng)目中用到的非常有用的功能點(diǎn)。
用golang寫的服務(wù),如果我們要使用lua腳本中定義的函數(shù)怎么辦呢?在gopher-lua提供了響應(yīng)的方法,在其站點(diǎn)也有非常好的例子來(lái)說(shuō)明:
首先用DoFile方法來(lái)加載lua腳本,在腳本中定義需要lua函數(shù)
其次使用CallByParam函數(shù)進(jìn)行調(diào)用
L := lua.NewState()defer L.Close()if err := L.DoFile("double.lua"); err != nil { panic(err)
}if err := L.CallByParam(lua.P{
Fn: L.GetGlobal("double"), // 獲取double這個(gè)函數(shù)的引用
NRet: 1, // 指定返回值數(shù)量
Protect: true, // 如果出現(xiàn)異常,是panic還是返回err
}, lua.LNumber(10)); err != nil { // 傳遞輸入?yún)?shù):10
panic(err)
}
ret := L.Get(-1) // 獲取返回結(jié)果值L.Pop(1) // 從堆棧中扔掉返回結(jié)果GopherLua的函數(shù)調(diào)用是通過(guò)堆棧來(lái)進(jìn)行的,調(diào)用前把需要傳遞給函數(shù)的參數(shù)壓到棧里,函數(shù)執(zhí)行完成之后再將結(jié)果放入堆棧中,調(diào)用方通過(guò)在堆棧頂部拿函數(shù)執(zhí)行結(jié)果。
go調(diào)用lua函數(shù)在flow項(xiàng)目中用的相對(duì)較少,用的較多的是下面一種:lua腳本中調(diào)用go函數(shù);因?yàn)楹芏鄰?fù)雜操作其實(shí)用lua來(lái)做還是有點(diǎn)復(fù)雜和不安全,尤其有些公共操作或者復(fù)雜的db操作。所以好的做法是在go中把函數(shù)封裝好,再在外部寫lua腳本,執(zhí)行的時(shí)候可以調(diào)用go函數(shù),這樣既可以滿足lua腳本的靈活性,也極大的擴(kuò)展了lua的能力和減低了編寫復(fù)雜度。
先看看其基本使用方法,也是通過(guò)官網(wǎng)的例子來(lái)說(shuō)明。
func Double(L *lua.LState) int {
lv := L.ToInt(1) // 獲取七個(gè)參數(shù)
L.Push(lua.LNumber(lv * 2)) // 把計(jì)算結(jié)果壓棧
return 1 // 返回計(jì)算返回參數(shù)的個(gè)數(shù)}func main() {
L := lua.NewState() defer L.Close()
L.SetGlobal("double", L.NewFunction(Double)) // 注冊(cè)函數(shù)}首先再gopher-lua中有一個(gè)類型lua.LGFunction ,這個(gè)類型就是一個(gè)函數(shù)類型,它固定了函數(shù)的入?yún)⒑统鰠ⅲ雲(yún)⒕褪莑ua.LState的一個(gè)引用,返回值就是一個(gè)int。如下面的定義,如果需要跟多的參數(shù)就需要使用堆棧或者對(duì)lua.LState擴(kuò)展成員的方式。在執(zhí)行完成之后也是通過(guò)堆棧或者對(duì)lua.LState擴(kuò)展成員的方式把返回值傳遞出去。
函數(shù)的注冊(cè)有多種方式,上面是一種方式,另外我從網(wǎng)上還看到一種方式,就是使用lua的table的方式。
myfuns := L.NewTable()
L.SetGlobal("myfuns", myfuns)
// 注冊(cè)函數(shù)
L.SetField(myfuns, "gofun1", L.NewFunction(gofun1))
....
// 調(diào)用方式
err := L.DoString(`
test = myfuns:gofun1("test")
`)這里面不方便的一點(diǎn)就是參數(shù)的傳遞和獲取不是很直觀,很多時(shí)候需要二次分裝調(diào)用函數(shù)。這一點(diǎn)有點(diǎn)不方便。其它還好。
GopherLua可以創(chuàng)建一個(gè)非常干凈的Lua解釋器實(shí)例,不加載任何系統(tǒng)模塊。然后由程序員自己提供的模塊注冊(cè)進(jìn)去,給內(nèi)嵌腳本提供一個(gè)安全的沙箱運(yùn)行環(huán)境。
關(guān)于golua虛擬機(jī)的使用分析問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
網(wǎng)站題目:golua虛擬機(jī)的使用分析
網(wǎng)址分享:http://chinadenli.net/article6/jgpoog.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)、網(wǎng)站改版、電子商務(wù)、網(wǎng)站收錄、網(wǎng)站建設(shè)、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)