继续上文做一些细节补充。
lua多线程锁
1、上章节中使用的锁为全局锁,如下:
#if !defined(lua_lock)
extern void hx_lua_lock();
extern void hx_lua_unlock();
#define lua_lock(L) hx_lua_lock()// ((void) 0)
#define lua_unlock(L) hx_lua_unlock() //((void) 0)
#endif
2、锁只需要锁住公共资源即可,没必要使用全局锁。便做了如下优化:(纠正:移除该部分,建议使用上述的全局锁)
#if !defined(lua_lock)
extern void hx_lock(void*);
extern void hx_unlock(void*);
#define lua_lock(L) hx_lock(L->lock)// ((void) 0)
#define lua_unlock(L) hx_unlock(L->lock) //((void) 0)
#endif
在struct lua_State 中添加void *lock成员,其实也就是 xSemaphoreHandle lock。具体锁功能用信号量实现即可。
纠正:(2020/8/13)
多线程中的lua锁还是的用全局公用锁,经过大量测试和填坑得出来的结果。
lua线程结束垃圾回收及资源释放
线程结束后需要处理线程所占用的资源,其中包括线程堆栈,动态分配的内存以及lua资源。
static void _task(void *arg)
{
lthread_t *thread = (struct lthread *)arg;
luaL_checktype(thread->L, 1, LUA_TFUNCTION);
int inParamLen = lua_gettop(thread->L) - 1;
int status = lua_pcall(thread->L, inParamLen, 0, 0);
if (status != LUA_OK)
{
const char *msg = lua_tostring(thread->L, -1);
printf(" thread pacll err:<%d> %s\r\n", status, msg);
}
//释放线程占用的lua资源
luaL_unref(thread->PL,LUA_REGISTRYINDEX,thread->function_ref);
luaL_unref(thread->PL,LUA_REGISTRYINDEX,thread->thread_ref);
//动态分配资源
free(thread);
//lua锁
vSemaphoreDelete(thread->L->lock);
//释放线程资源
vTaskDelete(NULL);
}
测试test.lua
--起始占用资源
collectgarbage('collect')
print('main1>',task.msg(),collectgarbage("count"))
task.run(function(data)
--开辟线程占用资源
print('task>',task.msg(),collectgarbage("count"),data.value)
end,{value=233})
--适当延时等待线程结束
os.sleep(500)
--线程结束后所占用的资源
collectgarbage('collect')
print('main2>',task.msg(),collectgarbage("count"))
测试结果:
main1> 54464 15.4668
task> 52208 16.05762 233
main2> 54464 15.4668
[execute success]
对比前后,FreeRTOS剩余堆栈空间和lua占用空间一致,创建的线程所使用到的资源已全部释放。
注意:
//释放线程占用的lua资源
luaL_unref(thread->PL,LUA_REGISTRYINDEX,thread->function_ref);
luaL_unref(thread->PL,LUA_REGISTRYINDEX,thread->thread_ref);
上诉两句是释放注册的资源,如果不解除,lua将无法回收该部分资源。会造成lua内存泄露。