Lua C API:太多的lua_states导致错误?
2010-7-15 8:46:29
收藏:0
阅读:209
评论:1
我们正在多台计算机上工作,执行用c / c++编码并使用lua api的程序,它们每一个都会因不同的错误而崩溃。通常这要么是一个分段错误,其回溯将我们带回到由liblua进行的调用,要么是在尝试调用nil值时通常会发生的错误,就好像它是一个函数一样。
奇怪的是,它运作得非常好,直到我们达到一定数量的“状态”(不,我们绝对需要多个状态,只有一个不够)。它们可能指的是相同的文件-再次说明,直到打开的状态少于某一数量,文件才能正常工作-或者不是。
以下是它们如何打开、注册和关闭,以防在使用多个状态时出现错误:
lua_State *state=lua_open();
luaL_openlibs(state)
luaL_loadfile(filename.c_str());
...
lua_register(state,"function",function); //dozens of them
...
lua_close(state);
在所有寄存器都完成之前,不会创建任何其他状态,不论它是否关闭取决于状态的使用位置。
以下是在分段错误期间所得到的信息:
#0 0x0013fe79 in ?? () from /usr/lib/liblua5.1.so.0
#1 0x0013325b in lua_pushlstring () from /usr/lib/liblua5.1.so.0
#2 0x001442ba in ?? () from /usr/lib/liblua5.1.so.0
#3 0x00144b61 in luaL_pushresult () from /usr/lib/liblua5.1.so.0
#4 0x00144de5 in luaL_gsub () from /usr/lib/liblua5.1.so.0
#5 0x0014fb52 in ?? () from /usr/lib/liblua5.1.so.0
#6 0x0014ffb7 in ?? () from /usr/lib/liblua5.1.so.0
#7 0x0013839a in ?? () from /usr/lib/liblua5.1.so.0
#8 0x00138834 in ?? () from /usr/lib/liblua5.1.so.0
#9 0x001337a5 in lua_call () from /usr/lib/liblua5.1.so.0
#10 0x0014f3ea in ?? () from /usr/lib/liblua5.1.so.0
#11 0x0013839a in ?? () from /usr/lib/liblua5.1.so.0
#12 0x00138834 in ?? () from /usr/lib/liblua5.1.so.0
#13 0x00133761 in ?? () from /usr/lib/liblua5.1.so.0
#14 0x00137ea3 in ?? () from /usr/lib/liblua5.1.so.0
#15 0x00137f05 in ?? () from /usr/lib/liblua5.1.so.0
#16 0x00133588 in lua_pcall () from /usr/lib/liblua5.1.so.0
相关代码如下:
lua_getglobal(L,"require");
lua_pushstring(L,"function");
if(!lua_pcall(L,1,0,0))
{
...
作为函数的字符串并不是错误的,在打开的状态少于某种数量的情况下完全正常工作。
当它输出“nil值”错误时,它意味着我们没有从程序内部使用相关的lua_register调用,但对于所有其他状态都是相同的,而且它们都没有任何问题。
我认为这可能是由于某些内存泄漏引起的,但我真的不知道为什么,因为所有状态都已关闭。
这是否与lua api本身有关(例如可能一次打开一个预定的状态数量)?我知道我没有提供太多细节,但这真的几乎是与lua相关的所有代码。
编辑:我忘了包括“require”语句(我称之为推模块),但它已经在代码中了(因此不是它不起作用的原因),对此感到抱歉。
该程序是单线程的。某些对象的属性具有lua状态,因此有多个状态。
错误消息表明它找不到应该使用的文件...实际上它存在,而且再次打开少量状态时可以使用,没有任何问题。
原文链接 https://stackoverflow.com/questions/3212475
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
你提供的调用代码片段没有意义。你有:
lua_pushstring(L,"function"); if(!lua_pcall(L,1,0,0)) { ...
这并没有显示检索名为“function”的函数,而是用字符串“function”作为其第一个参数,调用了栈顶的任何内容。
也许你的意思是:
lua_getglobal(L,"function"); if(!lua_pcall(L,0,0,0)) { ... // 成功 } else { // 检查有用信息的调用错误 fprintf(stderr, "lua_pcall: %s\n", lua_tostring(L,1)); }
编辑:从
lua_pcall()
返回的错误字符串可能提供有用信息。想要更多信息,可以将适当的错误函数放在堆栈上,并将其索引作为第四个参数传递给lua_pcall
。debug.traceback
是一个不错的选择。void callback(lua_State *L, const char *fname) { int status lua_getglobal(L,"debug"); // 将debug.traceback放在堆栈上 lua_getfield(L,-1,"traceback"); lua_remove(L,-2); lua_getglobal(L,fname); // 将函数放在堆栈上 status = lua_pcall(L,0,0,-2) if (!status) // 调用并没有参数或返回值 { // 成功 } else { // 检查有用信息的调用错误 fprintf(stderr, "lua_pcall returned %d: %s\n", status, lua_tostring(L,1)); lua_pop(L,1); // 从堆栈中删除错误消息 } lua_pop(L,1); // 从堆栈中删除debug.traceback }
编辑2:在你的澄清后,它仍然没有意义。
你的代码有以下片段:
lua_register(state,"function",function); //几十个 ...
稍后有:
lua_getglobal(L,"require"); lua_pushstring(L,"function"); if(!lua_pcall(L,1,0,0)) { ...
第一个片段创建了一些全局变量,它们的值为C函数。你可以像我答案中所述的那样,使用
get_global()
和lua_pcall()
来调用这些函数。第二个片段检索名为
require
的全局变量,并将其作为“function”字符串的唯一参数调用它。在Lua中,它等同于require"function"
,它将查找一个名为“function”的模块,在通常的方式中。即使调用require()
,检查并报告错误消息也是一个好主意。在这种情况下,它可能会告诉您require
查找的长列表中没有名为“function”的模块。但是,你的代码中并没有真正调用函数本身。
但是这里有一个更大的问题。不清楚为什么你需要多个Lua状态,特别是在单线程的程序中。可能使用协程更合适吗?
在使用多个状态的情况下,必须记住每个状态与其他所有状态之间的极度隔离。将值从一个状态移动到另一个状态的唯一方法是使用C API从一个状态检索值并将其推入另一个状态。协程有一些独立状态的优点,同时共享一组公共全局变量。