2013-06-22 10 views
3

我有一個HTTP服務器需要處理來自Lua代碼的HTTP請求。從C代碼,我調用一些Lua的C API這樣(的想法來自here):什麼是從C調用Lua的禁食方式?

lua_State *L = luaL_newstate(); 
luaL_openlibs(L); 
luaL_loadfile(L, "some.lua"); 
lua_pcall(L, 0, 0, 0); /* preload */ 
lua_getglobal(L, "handle"); 
lua_pushstring(L, "http_request"); 
lua_pcall(L, 1, 1, 0); 
lua_close(L); 

這一串代碼運行每個HTTP請求。在多線程工作環境下,此代碼具有相當的性能成本(從20000tps到100tps)。我想知道是否有更有效的方法來調用C的Lua代碼?


更新

當我註釋掉所有這些Lua的C API調用,我可以做一個20000tps。但是當打開這個API調用時,100tps。當在some.lua(刪除require調用,只加載一個空的Lua文件)進行一些更改,然後性能達到約15000tps。

因此,至少這些API調用成本約爲5000tps,如何使這個API調用更快?

+2

邑。除了'lua_pcall()'以外的所有功能。 – 2013-06-22 03:03:35

+1

多線程可以共享相同的'lua_State'嗎? – coanor

+0

所有對'lua_State'的'lua_'調用都不能同時發生。這就是每個線程擁有一個Lua狀態的原因。 – Deco

回答

2

對每個Lua狀態使用一個線程安全的隊列,並使隊列中的狀態在無限循環中彈出。如果隊列爲空,則讓狀態等待插入隊列時觸發的條件。 我建議LuaJIT,因爲它會優化原始線程API調用以接近接近C的速度。

除非您正在處理大量的HTTP請求,否則這將不會顯着受益(如dsign所述)。

注意:這種方法涉及重複使用Lua狀態來處理多個請求。如果這是一個安全問題,你可能可以在會話超時時間內對每個會話的Lua狀態做些什麼......但我不確定。 (這將是有狀態的服務器 - 客戶端合作關係中的一個有趣的實驗!您可以使用Lua狀態來保存用戶的整個會話,然後在有新請求時從睡眠中恢復...這將會很快)。

+0

@ Deco:根據你的回答,有兩種選擇,在每個客戶端或工作者中插入一個'lua_State'(作爲'void * plugin'字段在其定義中),沒有觸發器或隊列相關的構造(隊列可能需要互斥操作) 。而在客戶端,這似乎是一個會話,在工作人員似乎重用'lua_State'爲工人接受的各種客戶端,可能會有一些安全問題。你提醒我這一點,非常感謝。 – coanor

相關問題