【发布时间】:2014-08-26 10:35:31
【问题描述】:
我正在试验一种游戏机制,让玩家可以在游戏内的计算机上运行脚本。脚本执行将在游戏级别受到资源限制,每次滴答需要一定数量的指令。
以下概念验证演示了沙盒和任意用户代码限制的基本级别。它成功运行了约 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)
-- read script and set the environment
f = loadfile(fn, "t")
debug.setupvalue(f, 1, {print = print})
-- create a coroutine and have it yield every 50 instructions
local co = coroutine.create(f)
debug.sethook(co, coroutine.yield, "", 50)
-- demonstrate stepped execution, 5 'ticks'
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 上发布了bug report。它讨论了潜在的问题(线程没有像 Lua 规范中那样被垃圾收集)并提出了一些解决方法。
【问题讨论】:
标签: java multithreading lua coroutine luaj