Come passare i dati tra più Lua State (multi-thread)?

Io avvio il pool di connessioni Redis in redis.lua , chiamando da C, ho uno stato redis_lua_state , questo stato Lua è avviato globalmente una volta e gli altri thread ottengono solo da esso.

Mentre arriva una richiesta HTTP (thread di lavoro), devo recuperare una connessione redis da redis_lua_state , quindi un altro stato Lua per caricare altri script Lua, e questi script useranno questa connessione redis per comunicare con Redis, come fare? O come progettare i miei script Lua per renderlo semplice?


Esempio di codice:

  /* on main thread, to init redis pool connection */ lua_State *g_ls = NULL; lua_State *init_redis_pool(void) { int ret = 0; g_ls = luaL_newstate(); lua_State *ls = g_ls; luaL_openlibs(ls); ret = luaL_loadfile(ls, "redis.lua"); const char *err; (void)err; /* preload */ ret = lua_pcall(ls, 0, 0, 0); lua_getglobal(ls, "init_redis_pool"); ret = lua_pcall(ls, 0, 0, 0); return ls; } /* worker thread */ int worker() { ... lua_State *ls = luaL_newstate(); ret = luaL_loadfile(ls, "run.lua"); /* How to fetch data from g_ls? */ ... lua_getglobal(ls, "run") ret = lua_pcall(ls, 0, 0, 0) lua_close(ls); ... return 0; } 

Se i tuoi stati Lua sono separati, allora non c’è modo di farlo. Il tuo thread di lavoro dovrà inizializzare la connessione Redis ed elaborarlo.

Un modo per farlo è implementare la copia delle variabili tra gli stati Lua sul lato C. Ho fatto una cosa simile nel mio progetto ERP, ma richiede un po ‘di problemi, specialmente quando si tratta di copiare i dati degli utenti.

Quello che ho fatto è stato implementare una sorta di una variabile super globale (una class C nella mia istanza) che è implementata come __index e __newindex della tabella globale, che è un proxy per la tabella globale Lua predefinita. Quando si imposta una variabile globale, __newindex lo copierà in quella super globale. Quando un altro stato Lua tenterebbe di accedere a quello globale, lo recupererebbe dalla stessa struttura.

E poi la connessione redis potrebbe essere un mutex locked, quindi quando uno stato lo accede, l’altro non può, per esempio.

Ovviamente c’è il problema di accedere ai globals predefiniti di Lua di cui devi anche occuparti.

In alternativa, puoi controllare le corsie di Lua , se questa è un’opzione (non ho esperienza con Redis, quindi non so come aprire Lua, ma vedo che hai pieno accesso a C api, quindi dovrebbe funzionare).