lua_State和luaL_newstate,luaL_openlibs及lua_close

本文介绍了Lua虚拟机的核心结构lua_State的定义与创建过程,并详细解释了luaL_newstate函数的作用及luaL_openlibs如何加载标准库。此外还讨论了lua_close函数如何释放虚拟机资源。

1,lua_State在Lua中的定义如下:
 struct lua_State {
      CommonHeader;
      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;  /* stack base */
        int stacksize;
        unsigned short nny;  /* number of non-yieldable calls in stack */
        unsigned short nCcalls;  /* number of nested C calls */
        lu_byte hookmask;
        lu_byte allowhook;
        int basehookcount;
        int hookcount;
        lua_Hook hook;
        GCObject *openupval;  /* list of open upvalues in this stack */
        GCObject *gclist;
        struct lua_longjmp *errorJmp;  /* current error recover point */
        ptrdiff_t errfunc;  /* current error handling function (stack index) */
        CallInfo base_ci;  /* CallInfo for first level (C calling Lua) */
         };

2,lua_State的生成

        不知道是不是老的版本,我在网上看到有网友的例子里这样写:
   lua_State *L = lua_open();  /* opens Lua */
        我下了Lua5.2编译后执行例子是不行的,找了lua源码也没有找到lua_open()的定义。暂不论它,现在生成lua_State对像的方式应如下:
   lua_State *L = luaL_newstate();
   luaL_newstate在源码中的定义如下:
   LUALIB_API lua_State *luaL_newstate (void) {
     lua_State *L = lua_newstate(l_alloc, NULL);
     if (L) lua_atpanic(L, &panic);
     return L;
   }
3,luaL_openlibs在源码中的定义:
   LUALIB_API void luaL_openlibs (lua_State *L) {
     const luaL_Reg *lib;
     /* call open functions from 'loadedlibs' and set results to global table */
     for (lib = loadedlibs; lib->func; lib++) {
       luaL_requiref(L, lib->name, lib->func, 1);
       lua_pop(L, 1);  /* remove lib */
     }
     /* add open functions from 'preloadedlibs' into 'package.preload' table */
     luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
     for (lib = preloadedlibs; lib->func; lib++) {
       lua_pushcfunction(L, lib->func);
       lua_setfield(L, -2, lib->name);
     }
     lua_pop(L, 1);  /* remove _PRELOAD table */
   }
   官方文档说明:Opens all standard Lua libraries into the given state.
   很简单,把所有标准类库加载到指定的虚拟机。疑问:有没有方法指定一个标准库到指定的虚拟机呢?
4,意义
   从网上找到以下一段资料:“Lua脚本的编译执行是相互独立的,在不同的线程上执行。通过luaL_newstate()函数可以申请一个虚拟机,返回指针类型              lua_State。今后其他所有Lua Api函数的调用都需要此指针作为第一参数,用来指定某个虚拟机。”
   中文大家都认识,不多说了,肤浅的认识是lua_State代表一个lua虚拟机对像,luaL_newstate()分配一个虚拟机。lua类库管理着所有的虚拟机。
5,lua_close
   代码:
   LUA_API void lua_close (lua_State *L) {
     L = G(L)->mainthread;  /* only the main thread can be closed */
     lua_lock(L);
     luai_userstateclose(L);
     close_state(L);
   }
   文档说明:
   Destroys all objects in the given Lua state (calling the corresponding garbage-collection metamethods, if any) and frees all dynamic memory used by this state. On several platforms, you may not need to call this function, because all resources are naturally released when the host program ends. On the other hand, long-running programs, such as a daemon or a web server, might need to release states as soon as they are not needed, to avoid growing too large.
   销毁指定虚拟机的所有对像(如果有垃圾回收相关的无方法则会调用该方法)并收回所有由该虚拟机动态分配产生的内存,在有些平台下我们不需要调用此函数,因为当主程序退出时,资源会被自然的释放掉,但是但一个长时间运行的程序,比如后台运行的web服务器,需要立即回收虚拟机资源以避免内存过高占用。

<think>好的,用户想知道如何在Lua中清空lua_State *L。首先,我需要回忆Lua的API相关函数。Lualua_State代表一个独立的执行环境,通常每个线程或协程都有一个。用户提到的“清空”可能是指重置这个状态,移除所有全局变量、加载的库、注册的表等,使其恢复到初始状态。 首先,Lua标准库中没有直接提供清空现有lua_State的函数。常见做法是关闭当前state并重新创建一个新的。因为lua_close(L)会销毁L,之后可以调用luaL_newstate()生成新环境。这种方法简单有效,避免了手动清理的复杂性,尤其是在涉及复杂引用资源时更安全。 但用户可能不想关闭state,而是希望重复使用现有的。这时候需要考虑手动清理。例如,通过lua_settop(L, 0)来清空栈,但这不影响全局变量或注册的表。要彻底清理,可能需要遍历全局表(_G)并逐一删除键值对。但这样做可能不彻底,因为某些库可能在其他注册表中留有数据。此外,用户自定义的metatable或upvalues也可能残留。 另外,Lua的某些扩展库或绑定可能持有对Lua对象的引用,直接重置state可能导致内存泄漏或资源未释放。因此,最佳实践仍然是重建state而非重置。用户如果有性能顾虑,可以预编译常用的代码块,并在新state中快速加载。 总结下来,回答应该分两种情况:推荐关闭并重建state,或者谨慎手动清理。同时要指出潜在风险,确保用户了解不同方法的适用场景限制。</think>在Lua中清空$lua\_State\ *L$需要根据具体需求选择以下两种方法: ### 方法1:销毁并重建(推荐) ```c lua_close(L); // 释放所有关联资源 L = luaL_newstate(); // 创建全新的lua_State实例 luaL_openlibs(L); // 重新加载标准库(可选) ``` 此方法通过销毁原有$lua\_State$对象并重建新实例实现彻底清空。适用于需要完全重置执行环境且不保留任何历史数据的场景[^1]。 ### 方法2:手动清理(高风险) ```c lua_settop(L, 0); // 清空调用栈 lua_pushnil(L); while (lua_next(L, LUA_REGISTRYINDEX)) { // 遍历注册表 lua_pop(L, 1); // 谨慎操作,可能破坏核心功能 } ``` 此方法尝试手动清理调用栈注册表,但存在以下风险: 1. 可能残留全局变量元表 2. 可能破坏已加载库的内部状态 3. 无法释放非Lua管理的资源(如C对象)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值