lua_State *lua_newthread(lua_State *L);
上面这个函数返回一个代表这个新线程的lua_State 型指针,并且同时将这个新的线程作为thread类型推进栈中,如: L1 = lua_newthread(L);
经过上面这步,我们就有了两个线程了,且两个线程都实际上在同一个lua state内部。每个线程都有自己独立的栈,新的线程L1有个空的栈;而L线程则将新的线程存储在其自身栈的栈顶。如: e.g.
printf("%dn",lua_gettop(L1)); --0 新的线程的栈是一个空的栈
printf("%sn",luaL_typename(L,-1)); --thread 代表在栈顶是一个线程,即新的那个线程
除了主线程之外,其余的这些线程都是受garbage collection管理的对象,和Lua其余的这些对象一样。当创建了一个新的线程,以thread类型将这个线程推进至栈中,保证了这个线程不会被回收掉。我们应该确保不使用那些不确定还是否在栈中的线程。每次调用Lua的API都可能会触发回收那些不在栈中的线程,即便这个线程还在使用中,如: lua_State *L1 = lua_newthread(L);
lua_pop(L,1); /* L1 is garbage*/
lua_pushstring(L1,"helloe"); /* danger */
调用lua_pushstring的时候可能会触发garbage collector回收掉L1,即便此时仍然在使用这个线程。为了避免遇到不可预期的错误,应该始终对我们在使用中的线程保持引用,for instance in the stack of an anchored thread or in the registry.
新创建的线程,可以和使用主线程一样使用。可以从该线程的栈中推进和推出元素,可以使用栈来调用函数等等。这里介绍一个函数lua_xmove(L1,L,1),这个函数的作用是做同一个state中的栈的数据移动,如lua_xmove(F,T,n),就是从栈F中推出一个 元素,然后推进至栈T中。做这个操作我们甚至都不需要创建额外新的线程,只需要在主线程中处理就可以了。在这里使用多线程的前提是实现协同程序,以便我们可以延缓或者恢复某个线程的执行。恢复执行某个函数,在这里就需要函数:lua_resume 来支持:
int lua_resume(lua_State *L,lua_State *from ,int nary);
如我们使用lua_pcall 一样,如果我们想运行一个协同程序,我们可以使用lua_resume函数:将要调用的函数,参数推进至栈中,函数参数narg代表传递的参数的数量。(from 参数指的是执行这个调用的线程所在的state)。主要的行为类似于lua_pcall,但还是有三个不同的地方:1、lua_resume没有代表返回值数量的参数,函数总是会返回所有的返回结果;2、没有给消息句柄用的参数,错误不会在栈中触发,因此可以在错误之后检测栈(~~~没看懂);3、如果在运行的这个程序被挂起了,lua_resume 返回一个特殊代码:LUA_YIELD ,且将在state中的线程保留下来留给之后重新调用。
协同程序也能调用C函数,这些C函数也能回调其他的Lua函数。
本文发布于:2024-01-28 02:16:28,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17063793924068.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |