1

我一直在看 lua 和 lvm.c。我非常想实现一个接口来允许我控制 VM 解释器状态。

lua 内部的协作多任务处理对我不起作用(用户贡献的代码)

调试钩子只让我到达那里的大约 50%,指令执行限制,但它引发了一个异常,它只会使正在运行的 lua 代码崩溃——但我需要能够进一步调整它。

我想创建一个运行数十万个 lua 用户脚本的系统 - 单个线程将无法工作,并且执行限制会让初学者感到头疼,我还要控制执行速度。但最终

while true do

end

将永远执行,我真的不在乎它是。

我可以查看的任何想法、帮助或其他实现?

编辑:这与沙盒无关,假装我是该领域的专家进行此对话

编辑:我不想使用内部运行的基于 lua 代码协程的控制器。

编辑:我想运行一个线程,并管理大量用户贡献的 lua 脚本,外部进程级控制机制根本无法扩展。

4

4 回答 4

2

可以搜索 Lua Sandbox 的实现;例如,这个wiki 页面SO question提供了一些指示。请注意,沙盒的大部分工作都集中在不允许您执行错误代码上,但不一定要防止无限循环。为了更好地控制,您可能需要将 Lua 沙盒与LXCcpulimit 之类的东西结合起来。(根据评论不相关)

如果您正在寻找基于 Lua 的、轻量级的但不一定 100% 万无一失的东西,那么您可以尝试在单独的协程中运行您的客户端代码,并在该协程上设置一个调试钩子,该钩子将每第 N 行触发一次。在那个钩子中,您可以检查您正在运行的进程是否超出了它的报价。您还需要处理新启动的协程,因为它们需要设置自己的钩子(您需要禁用 coroutine.create/wrap 或用设置您需要的调试钩子的东西替换它们)。

这种情况下的代码可能如下所示:

local coro = coroutine.create(client_func)
debug.sethook(coro, debug_hook, "l", 1000) -- trigger hook on every 1000th line

这不是万无一失的,因为它可能会阻塞某些 IO 操作,并且调试钩子在那里无济于事。

[根据更新的问题和评论进行编辑]

在“无基于 lua 代码协程的控制器”和“无外部进程控制机制”之间,我认为您别无选择。可能您唯一的选择是为每个用户脚本运行一个虚拟机,并以某种方式给这些虚拟机打勾(最近有一个关于 SO 的问题,但我找不到)。在走这条路之前,仍然会尝试使用协程(应该可以轻松扩展到数万;Tir 声称支持 1M 活跃用户和基于协程的架构)。

该机制大致如下所示:您安装调试钩子,如上所示,然后从该钩子返回到控制器,然后控制器决定要恢复的其他协程(用户脚本)。我在我一直在开发的Lua 调试器中使用了这种机制(尽管它只适用于一个客户端脚本)。这并不能保护您免受可能阻塞的 IO 调用的影响,因此您可能仍需要在 VM 级别有一个看门狗来查看它是否被阻塞的时间超过了需要的时间。

如果您需要序列化和反序列化运行代码片段以保留上值等,那么Pluto可能是您唯一的选择。

于 2012-09-12T19:24:11.507 回答
0

看看实施lua_locklua_unlockhttp://www.lua.org/source/5.1/llimits.h.html#lua_lock

于 2012-09-14T14:01:05.560 回答
0

看看这个, https://github.com/amilamad/preemptive-task-scheduler-for-lua 我维护了这个项目。它是一个用于运行 lua 代码的非阻塞抢占式调度程序。适用于长时间运行的游戏脚本。

于 2018-01-16T10:18:51.790 回答
0

看看露露。它是在 lua 上编写的 lua VM。它适用于 Lua 5.1 对于较新的版本,您需要做一些工作。但那时你真的可以做一个调度器。

于 2016-01-30T22:00:48.883 回答