lua源碼分析
A. 伺服器程序源代碼分析之二:php-fpm
php作為排名top2 互聯網開發工具,非常流行,可以參考:中國最大的25個網站採用技術選型方案
php這個名稱實際上有兩層含義
直接定義:
php-fpm從php5.3.3開始已經進入到php源代碼包,之前是作為patch存在的
很少人會去讀php本身源代碼,我6年前解決php內存泄露問題的時候做了些研究,最近再查看了一番,發現php的開發者很有誠意,這是一款非常出色的伺服器軟體,支持如下
在linux伺服器上,如果不設置 events.mechanism ,那麼默認就是採用epoll,所以
php-fpm的IO模型&並發處理能力和nginx是完全一致
nginx以性能卓越聞名,大部分程序員都認為php效率低下,看了源代碼,才知道這是傳奇啊
在高性能部署的時候,大家往往會針對性的優化nginx 。我自己之前部署php程序也犯了錯誤,8G內存的server,php-fpm的max children都會設置128+,現在看來太多了,參考nginx的部署:
php-fpm配置為 3倍 cpu core number就可以了
php-fpm穩定性比nginx稍差 這是因為php-fpm內置了一個php解析器,php-fpm進程就和php程序捆綁了,如果php腳本寫得不好,有死循環或者阻塞在某個遠端資源上,會拖累載入它的php-fpm進程
而nginx和後端應用伺服器之間通過網路連接,可以設置timeout,不容易堵死的
php-fpm的fastcgi是短連接 我原以為是長連接的,看了代碼才知道也是短連接,處理一個request就關閉掉
php-fpm介面採用fastcgi 非常遺憾,php-fpm和fastcgi完全綁定了,無法獨立使用 。只能部署在支持http-fcgi協議轉換程序背後(nginx)。其實可以考慮在php-fpm代碼包裡面引入http協議支持,這樣php-fpm可以獨立運行,讓nodejs無話可說
php-fpm等同於OpenResty OpenResty是一個國人開發的nginx模塊,就是在nginx引入lua解釋器. 實際上,它和php-fpm的唯一差別就是一個採用php語法,一個用lua,所以OpenResty要作為nginx增強包使用還可以,要選擇它作為一個主要編程工具,沒有任何必要
從架構上來說,php-fpm已經做到最好,超過大多數 python部署工具,我再也不黑它了
B. lua 解密
lua文件加密
這其實是你的理解錯誤
並不是被真正的加密,而是被做成機器碼了,就是給機器看用的,所以也不可能復原
就像C代碼用VC編譯後生成EXE
不可再變回源代碼是一個原理的
只能教你怎麼把LUA源碼變成機器碼,
只要找到lua文件夾下的luac文件
在cmd下輸入
luac
targFileName
--
tar是目標文件名,就會生成對應的機器碼,
這只是你所謂的加密,解密就沒辦法了
C. lua解析器用什麼寫的
沒有匯編,只有C語言,而且是最基本的C語言。
lua官方的解釋器為保證lua解釋器的可移植性和可嵌入性,用純ANSI C寫的,即其中只有保持最大兼容要求的標准C語言代碼……通俗點說,沒有使用任何各種編譯器的方言語法以及更高版本的C語言語法,甚至沒有使用復雜的函數庫,在通俗點說就是只引入了std開頭的那些C語言庫,比如說常見的stdio.h和stdlib.h……
但是嵌入性是lua解釋器的基本要求之一,你可以將其嵌入到自己的程序裡面作為擴展,其本身也具有很強的擴展性,所以如果你問lua解釋器本身,毫無疑問是C語言,如果是嵌入了lua的產品可能成分就並不單純了……
源碼可在此處下載到,整個源碼只有五百來K,感興趣可以看一下:
http://www.lua.org/download.html
D. 求LuaStudio下載地址
軟體介紹
LuaStudio是一款非常好用的編程調試器軟體,它是一款真正意義上的IDE、集成了編輯、工程管理、調試、遠程調試等各種功能為一體,支持注入到宿主程序內對lua腳本進行調試,還可以設置斷點觀察變數的值,功能非常強大。
所需工具:點擊下載:LuaStudio(編程調試器)
功能特色
1、語法高亮
luastudio支持Lua編程語言的語法高亮。用戶可以自定義字體外觀名稱,字體大小,和其他格式的語法元素。
2、項目管理
luastudio提供了強大的項目管理功能。所有的項目管理功能,可從主菜單或項目可停靠的視圖上下文菜單訪問。
luastudio可以打開和管理在當時只有一個解決方案。一個解決方案可能包含一個或多個項目。一個項目可以有一個或多個文件夾,和一個文件夾可以包含一個或多個文件。
代碼段
luastudio為用戶提供了一套Lua代碼片段。這些片段可以用Lua源文件。luastudio會檢測當前在編輯單據類型,開關段設置和使用正確的文件。
3、lua腳本調試
luastudio提供了強大的調試功能,用戶可以調試個人Lua腳本由官方的Lua解釋器解釋,或調試嵌入式LUA腳本的其他應用程序中嵌入lua解釋器使用。luastudio會檢測到目標應用程序類型,然後決定調試器的工作方式,無需手動完成。
4、符號視圖
luastudio分析當前編輯lua的源碼,所有功能和他們的名單中提取符號觀。這意味著符號視圖顯示Lua源代碼的輪廓。正如你所看到的,將組織的輪廓樹的形式。如果項目中的符號視圖用戶雙擊,luastudio將跳線,函數的定義。
LuaStudio破解版安裝教程
1、下載軟體壓縮包文件,點擊「LuaStudio.exe」,根據提示完成軟體安裝
2、打開軟體,我們可以看到軟體提示的試用期到期時間為0天,
3、下載關閉LuaStudio程序,雙擊運行LuaStudio9.6.7無限試用補丁,點擊「清除使用痕跡」選項
4、再次打開LuaStudio,點擊「幫助」菜單----「注冊授權管理」,然後就可以看到提示29天後過期。
E. Lua源碼模塊分析
外部符號的前綴表示其來自的模塊:
在src / Makefile(5.1.1)中,mingw目標是不尋常的,因為它只構建lua(不是luac)。也可以添加mingw-cygwin目標。請參閱 BuildingLua中的 mingw注釋來解決。
在SRC / luaconf.h(5.1.1),LUA_PATH_DEFAULT指的是LUA_LDIR和LUA_CDIR,但LUA_CPATH_DEFAULT僅指LUA_CDIR的這些。 RiciLake 建議這可能是一個安全決策,其中C模塊需要比Lua模塊更多的信任。
在src / luaconf.h(5.1.1)中,有一個LUA_CDIR"loadall.dll",在 [3] [4]中 討論。
請參閱 GarbageCollection 和 EmergencyGarbageCollector中 的描述。
參見 LuaSourceTable
這在 BindingCodeToLua中 有所描述。
注意:「#define lmathlib_c」(和其他庫中的類似行)只存在於luaconf.h中的條件(由lhf注釋)。
F. Lua字元串拼接
之前研究lua中字元串拼接,看了一些文章都說 "table.concat" 高於 ".."。最近項目做優化,發現項目中使用table.concat的效率並不比..高,所以實際測試了一下。
1、一些文章說的"table.concat" 高於 "..",是在特定環境中才有效的,看一下他們使用的測試用例:
local str = "a"
local count = 100000
local start_time = os.clock()
local result = ""
for i=1,count do
result = result .. str
end
print("operatorConcatTime:" .. os.clock() - start_time)
local tbl = {}
for i=1,count do
table.insert( tbl,str)
end
table.concat(tbl)
print("tableConcatTime:" .. os.clock() - start_time)
運行後測試結果如上圖,運行效率明顯table.concat遠高於..。在上述測試用例中,「..」 每次只拼接一個字元串,一共拼了10000次。「..」每次拼接都會產生一個新的字元串,而在lua中每產生一個新的字元串都需要將該字元串存放在全局狀態表(global_State)的 strt 域中,隨著拼接次數增大,就會需要更大的空間存儲新的字元串,當達到一定大小時,舊的字元串就需要GC,伴隨著不斷的開辟新空間和GC,就導致性能降低。 而table.concat 底層拼接字元串的方式也是使用運算符.. ,但是其使用演算法減少了使用運算符..的次數,減少了GC,從而提高效率。主要思路:採用二分思想,用棧存儲字元串,新入棧的字元串與下方的字元串比較長度,大於則使用運算符..拼接成新字元串,並移除棧頂的字元串,不斷向下直至遇到長度更大的字元串或者棧底,這樣保持最大的字元串位於棧底,棧呈現金字塔的形狀,最終在使用運算符..將棧中的字元串拼接成最終的字元串。引用( Lua大量字元串拼接方式效率對比及原因分析_AaronChan的博客-CSDN博客_lua 字元串拼接 )。
2、而在實際項目中一般都是幾個字元串的拼接,拼接頻次高,拼接個數少。針對項目中實際情況,寫了如下測試用例測試:
(1)測試用例1:
function global_SpliceString (...)
local t = { ... }
return table.concat (t)
end
local count = 10 000
local sM1 = 0
local sM2 = 0
local start_time
collectgarbage("collect")
sM1 =collectgarbage("count")
print("sM1:",sM1)
local result = ""
start_time = os.clock()
for i = 1, count do
result =global_SpliceString("SELECT * FROM ", "QuestPlot", "WHERE sn='", i, "'")
end
print("CostTime:",(os.clock() - start_time))
sM2 =collectgarbage("count")
print("sM2:",sM2)
print("Genery Mem ory:" , (sM2 - sM1))
(2)測試用例2:
local count = 10 000
local sM1 = 0
local sM2 = 0
local start_time
collectgarbage("collect")
sM1 = collectgarbage("count")
print("sM1:",sM1)
local result = ""
start_time = os.clock()
for i = 1, count do
result = "SELECT * FROM" .. "QuestPlot" .. " WHERE sn='" .. i .."'"
end
print("CostTime:",(os.clock() - start_time))
sM2 =collectgarbage("count")
print("sM2:",sM2)
print("Genery Memory:",(sM2 - sM1))
(3)測試用例3:
local tb = {[1]= "SELECT * FROM ", [2] = "QuestPlot", [3] = " WHEREsn='", [4] = 100101, [5] = "'"}
collectgarbage("collect")
sM1 =collectgarbage("count")
print("sM1:",sM1)
local result = ""
start_time = os.clock()
for i = 1, count do
tb[4] = i
result = table.concat( tb )
end
print("CostTime:",(os.clock() - start_time))
sM2 =collectgarbage("count")
print("sM2:",sM2)
print("Genery Memory:",(sM2 - sM1))
測試結果如下所示:
(1)global_SpliceString:
(2)..
(3)table.concat:
為了模仿更真實的使用環境,以上三個測試用例中要拼接的字元串都有一個動態變化的字元串。通過結果比對,測試用例2和用例3的耗時和內存相差無幾,而測試用例1的耗時和內存明顯高出很多。通過查看lua源碼知道,在一個語句中用「..」連續拼接幾個字元串並不會產生中間字元串,而是會把所有需要連接的字元串都收集起來一起連接。所以table.concat和「..」的方式相差無幾。再看測試用例1,同樣使用table.concat,為什麼用例1的耗時和內存明顯增多。 是因為在 gobal_SpliceString() 方法中的 local t = { ... }, 每次調用這個方法都需要先構造一個table,然後才能使用table.concat。而table在lua中也屬於GC對象,table的創建需要消耗更多時間和內存。同時調用global_SpliceString也會有函數調用消耗,所以用例1的性能消耗是由構造table導致的。
3、總結:
通過以上分析,我們不能簡單的說table.concat和「..」誰的性能更好,還要根據具體使用場景,具體問題具體分析。一般如果一次拼接大量字元串並且要拼接的字元串基本都是固定的,可以使用table緩存起來,使用table.concat拼接;如果是動態的且比較少的字元串拼接,可以直接在一個語句中使用「..」連續拼接。
G. 請教lua如何反編譯,或者指點一下luadec的用法,請不要復制回答問題。
搜:Lua腳本反編譯入門教程。
H. lua語言實現中lua_State定義無法在源代碼中找到,只找到了typedef struct lua_State lua_State。求教!
你看的那個不是源碼,只是頭文件。
源代碼可以去官網下載
I. luacrul類庫-ftp問題分析/解決
問題:使用smart_pub.kkf2中的 function t.upload(sftpTab) 函數ftp上傳報錯;
改函數使用了 LuaCURL庫函數,網上先了解一下:
查了其他網站資料,對LUA的類庫解釋的很少,官網英文且解釋的不全面,不容易理解,
所以參考php的libcurl庫說明,語言不同,類似可以參考;
分析報錯信息,初步理解為文件目錄不存在,或者創建失敗;定位:
查看系統關鍵源碼設置:
源碼【順便在源碼上加了注釋,便於理解其他參數】
新增設置
測試問題解決:
還好之前使用過curl工具模擬webservice、rest客戶端報文測試,相對通用理解一些,curllib庫還有很多功能可能總結學習;
參考 http://luaforge.net/projects/luacurl/
http://underpop.free.fr/l/lua/luacurl/
https://www.cnblogs.com/endv/p/8433889.html