从另一个线程中断c++中的lua脚本
Break a lua script in c++ from another thread?
我目前正在用c++包装一个lua类,到目前为止进展顺利。但我想知道是否有什么方法可以阻止lua脚本为另一个线程运行(可能是在脚本的中间)。所以,如果我在线程1上运行lua脚本,我可以从线程2中断它吗?lua_close(...)
会这么做吗?
谢谢。
如果这是预期的情况,并且Lua脚本的大部分时间都花在Lua函数中(即不长,阻塞C调用),则可以安装一个调试挂钩,每隔N条指令检查一次"break flag"并中止脚本。请参阅Lua中编程的"调试库"部分。
那么一定有什么方法可以强制脚本停止?
不,没有。
Lua提供了一个线程安全保证:两个独立的lua_State
s(单独定义为lua_open
返回的不同对象)可以从两个不同的CPU线程中自由调用。线程A可以调用lua_State
X,线程B可以调用lua_State
Y。
这是Lua给您的唯一保证。Lua本质上是单螺纹的;它只提供这种保证,因为Lua的所有全局信息都包含在一个自包含的对象CCD_。
Lua的规则要求在任何时候只有一个线程与lua_State
对话。因此,Lua代码不可能执行,然后被外部C++代码暂停或暂停。这需要打破规则:其他线程必须调用该线程的lua_State
上的函数。
如果要中止正在进行的脚本,则必须使用调试挂钩。这将大大降低脚本的性能(如果这对你很重要的话)。您还需要线程同步原语,这样线程B就可以设置一个标志,线程a将读取并停止
至于你如何"中止"脚本,那。。。在最普遍的情况下是不可能的。原因如下。
lua_State
表示执行的Lua线程。它有一个堆栈,一个指向要解释的指令的指针,以及它当前正在执行的一些代码。"中止"这不是Lua的概念。Lua所拥有的是错误的概念。从Lua调用的C代码中调用lua_error
将导致它在该函数之外调用longjmp
。这也将展开Lua线程,它将向处理错误的最新函数返回一个错误。
注意:如果在C++代码中使用lua_error
,则需要将Lua编译为C++(从而通过异常处理而不是setjmp
/longjmp
来处理错误),或者在调用时需要确保每个带有析构函数的对象都不在堆栈中。如果不小心,在C++代码中将longjmp
调用是不可取的。
因此,如果您发出lua_pcall
来调用某个脚本,并且在调试挂钩中发出lua_error
,那么您将在lua_pcall
语句中返回一个错误。Lua的堆栈将被解开,对象将被销毁,等等。这很好。
这在常规情况下不起作用的原因很简单(此外,我不知道Lua对调用lua_error
的调试挂钩会有什么反应):Lua脚本也可以执行pcall
。错误将转到最近的pcall
语句,无论它是在Lua中还是在C.中
这个Lua脚本将混淆这种方法:
local function dostuff()
while true do end
end
while true do
pcall(dostuff)
end
因此,发出lua_error
并不能保证你会"中止脚本"任何人都可以抓住它们,所以你不能确保它们只在一个地方被抓住。
通常,您不应该希望中止正在执行的Lua脚本。这不是你应该做的事情。
- 使用 Lua 中的C++库对象
- 当使用Lua作为嵌入式语言(比如c++)时,有什么简单/方便的方法可以找到变量在Lua中的定义位置吗
- 如何防止 C API 注册表中的 Lua 回调被垃圾回收?
- 通过从 C++ 导入图像指针来处理 Lua 中的图像流
- 如何在不运行的情况下识别LUA脚本中的非初始化变量
- 从C 访问功能环境中的LUA变量
- CMAKE中的LUA静态链接
- QT线程中的Lua脚本
- 在c++中嵌入lua的问题
- 在Visual Studio 15社区中构建Lua的解决方案/项目结构
- 如何从C++中清除 lua 堆栈中的所有内容
- 将 Lua 中的变量提取到C++中
- 相当于C++中的Lua"和/或"?
- Lua 5.2 - C++对象中的对象(使用 lua_lightuserdata)
- 在C++中访问 Lua 函数的返回值,反之亦然
- 如何链接到 Lua 中的回调函数,以便在重新加载脚本时更新回调
- 从C++访问Lua中的表
- 从另一个线程中断c++中的lua脚本
- Visual Studio 2013 中的 Lua C API 堆栈可视化工具/查看器
- 访问C++中的lua类函数