我如何放弃 LuaJ 协程 LuaThread?
2017-5-23 11:45:46
收藏:0
阅读:78
评论:1
我正在尝试一种游戏机制,玩家可以在游戏内计算机上运行脚本。在游戏过程中,脚本的执行将受到资源的限制,每个时钟周期只能执行一些指令。
下面的概念验证演示了任意用户代码的基本沙盒和限制。它成功地运行了约250条不良设计的“用户输入”指令,然后丢弃了协程。不幸的是,Java进程永远不会终止。一些调查表明,由LuaJ为协程创建的“LuaThread”将永远挂起。
SandboxTest.java:
public static void main(String [] args){
Globals globals = JsePlatform.debugGlobals();
LuaValue chunk = globals.loadfile(“ res / test.lua”);
chunk.call();
}
res / test.lua:
function sandbox(fn)
- 读取脚本并设置环境
f = loadfile(fn,“t”)
debug.setupvalue(f,1,{print = print})
- 创建协程并使其每50个指令yield一次
local co = coroutine.create(f)
debug.sethook(co,coroutine.yield,“”,50)
- 演示分步执行,5“tick”
for i = 1,5 do
print(“tick”)
coroutine.resume(co)
end
end
sandbox(“ res / badfile.lua”)
res / badfile.lua:
while 1 do
print(“”,“badfile”)
end
文档建议认为不可恢复的协程将被垃圾回收,并将抛出一个OrphanedThread异常,从而发出信号LuaThread结束,但是这从未发生过。我的问题分为两个部分:
- 我是否做了一些根本性的错误以导致这种行为?
- 如果没有,我应该如何处理这种情况?从源代码中可以看出,如果我可以在Java中获取对
LuaThread的引用,我可以通过发出“中断()interrupt()”来强制放弃它。这是一个好主意吗?
参考:Lua / Java / LuaJ - Handling or Interrupting Infinite Loops and Threads
编辑:我已经在LuaJ SourceForge上发布了一个错误报告。它讨论了潜在问题(线程未像Lua规范中那样垃圾回收)并建议了一些解决方法。
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在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中获取用户配置主目录的跨平台方法
看起来这是LuaJ的局限性。我今年早些时候在Sourceforge上提出了一个问题,就像你也做的那样。
LuaThread类不存储对其创建的Java线程的引用,因此您无法在不修改LuaJ核心以暴露它们的情况下interrupt()这些线程:new Thread(this, "Coroutine-"+(++coroutine_count)).start();在没有添加适当的清理代码的情况下,中断这些线程可能会很危险。
你提供的
OrphanedThread文档还告诉我们,作用域是定义条件:"表示检测到不再引用的lua线程的错误子类。抛出此错误的Java线程应对应于作为协同程序使用的LuaThread,它不可能再次启动,因为没有更多与其关联的LuaThread的引用。而不是永远锁定资源,抛出该错误,应当一路落入线程的Thread.run()方法。"
您的代码示例并不会导致所有LuaThread引用消失,因此您不应该期望抛出异常。
CoroutineLib文档指出:“挂起但从未恢复执行的协同程序可能不会被垃圾收集器回收”,因此如果我没有弄错的话,从您在SourceForge上列出的代码中实际上应该_预期_发生OutOfMemoryError。LuaThread:52还指定:“应用程序不应捕获OrphanedThread,因为它可能会破坏luaj的线程安全性。”这是另一个障碍。Lua/J中空和非空的
while循环之间也似乎存在差异。如果我没记错的话,空循环(while true do end)不遵循所有协程钩子/刻度规则。 *因为空循环中没有任何动作,所以某些挂钩无法发生(我需要再测试一下,否则请纠正我!)。Minecraft的ComputerCraft模组中使用了我们正在寻找的功能的LuaJ分支版本,尽管它仅为该模组设计,不是开源的。