先讲下坑点:
1、lua_newthread 名称存在误导性,它只是拷贝一个栈,并不是创建一个线程。
2、不同的线程使用 lua_newthread 出来的栈去调用lua代码,也要加锁,否则也会异常。
3、在lua底层有两个宏:lua_lock与lua_unlock,默认的情况下,这两个东西不起作用,lua的作者的本意是希望我们在有并发需求的时候,重写这两个宏,所以只要是底层用到这两个宏的地方,如果被我们的并发线程调用到了,而我们没有重新定义这两个宏让它加锁,就会有问题。
个人牢骚:这种方式,要求我们用加锁的方式去帮助lua维护它的垃圾回收行为,个人认为非常蠢,而且会使lua的性能下降,根据统计,非常简单的代码,也是每次执行完之后也是几十次加解锁调用,更不要说复杂的东西了。
所以要在lua源码上解决这个问题的方法:
1、扩展lua_State结构,添加锁结构指针,必须是指针,或者是类似资源id的形式,总之,必须让需求并发lua_State访问到的是同一个锁对象。
2、lua_newstate里,给锁结构分配内存,初始化锁对象
3、lua_newthread里,单纯的拷贝指针即可。
4、close_state里处理一系列锁的释放与内存释放。
因为windows和linux的锁有区别,我自己是不用lua底层管理锁对象的,我的处理方法如下。
//lstate.h 里面再lua_State里添加代码
struct lua_State {
CommonHeader;
unsigned short nci; /* number of items in 'ci' list */
lu_byte status;
StkId top; /* first free slot in the stack */
global_State *l_G;
CallInfo *ci; /* call info for current function */
const Instruction *oldpc; /* last pc traced */
StkId stack_last; /* last free slot in the stack */
StkId stack; /*