克隆Lua状态

6

各位,有没有一种方法可以克隆Lua状态?

在我的游戏应用程序中,Lua虚拟机的初始化过程非常耗费时间(约1秒,因为同时加载了许多脚本)。我为每个自治体都有一个单独的Lua虚拟机,一旦自治体被创建,其Lua初始化会对FPS产生很大影响。

我在考虑以下方案:保留“预分叉”的Lua状态,然后简单地为每个自治体克隆它。这可行吗?


2
很多人都写Lua的时候都是错的,因为它不是一个首字母缩略词。你能否请修改上述内容,使其遵循标准命名规则。我们也不会写PYTHON。Lua只是一个由三个字母组成的名称。参见:http://www.lua.org/about.html - akauppi
3
哦,对不起。谢谢你提醒我。 - pachanga
你有找到做这件事的方法吗? - DShook
4个回答

4
你可以考虑使用Lua的协程来处理每个自主代理,而不是完全分离的虚拟机。协程是一种更轻量级的解决方案,但可能不适用于你的应用程序。
如果无法更改架构,可以尝试使用LuaJIT。它可能使初始化速度足够快以适合你的目的。
更多选项:
  1. Rings:“Rings是一个库,提供了一种从Lua内部创建新Lua状态的方法。它还提供了一种在创建者(主)和被创建者(从)状态之间进行简单通信的方法。”

  2. Pluto:“Pluto是一个库,允许用户将“Lua宇宙”的任意大部分写入到一个平面文件中,并在稍后将其读回到相同或不同的Lua宇宙中。”


我在考虑使用协程,但是我担心一个协程中的致命错误会影响其他协程,所以目前不是一个选项。感谢提供的链接!我目前正在查看LuaJIT和Rings。Rings似乎是我的问题的可能解决方案。 - pachanga
3
一个协程的致命错误不会以任何方式影响其他协程。只要我们谈论 Lua 代码——当然,用户提供的内容可能会按照其编程造成任何损害。 - Alexander Gladysh
我实际上需要克隆一个状态。这是为了我正在做的POS框架,我不希望编写脚本的人能够窃取信用卡密码。EMV库允许用户通过回调自定义屏幕,每个回调触发一个加载屏幕的lua协程。但是协程共享变量,我希望在密码调用期间对变量环境进行的所有修改都被回滚...我应该为此创建一个新问题吗? - Luiz Menezes

1
注意,此代码适用于 Lua 5.2 及以上版本。
您可以限制对此 VM 的访问。创建一个实例,其中包含所有所需的函数,该实例不会依赖于 _G(全局 Lua 状态),然后为每个客户端创建单独的表格。他们将使用它作为其全局命名空间。通过 _ENV 将表格设置为当前 _G 是可能的。这是一个相当难以在一篇文章中解释清楚的话题。简而言之,您为新客户端准备“虚拟”_G,然后只需替换客户端代码的 _G。我建议您从这里开始。 这就是重点。 local _ENV = t -- 更改环境。如果没有局部变量,这将更改整个块的环境 只需删除 local,即可更改所有后续代码的 _ENV。祝您实验成功!
附言:请不要忘记,您可以为 _ENV 和 _G 表格设置元表,并禁止更改该元表。Lua 在这方面确实非常灵活。

1

还有 Lanes (下载, 文档),在所有我所知的类似产品中都有 比较

关于 Rings,比较表格中说:

Rings 提供单独的 Lua 状态,但没有多线程。这使它变得简单,但不会使用超过一个 CPU 核心。

注意:比较表格说 Lanes 只会处理“非循环表”。它确实可以做循环,并处理函数、upvalues 等。它在 Lua 状态之间的拷贝是直接拷贝,不需要在中间转换成字符串。这使得它非常快速。


1

如果你使用的是Linux系统,你可以尝试由Lua语言作者之一开发的基于lperLPSM的实验性库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接