- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在试验一种游戏机制,让玩家可以在游戏内计算机上运行脚本。脚本执行将在游戏级别上受到资源限制,每刻指令数量有限。
以下概念验证演示了基本级别的沙盒和任意用户代码的限制。它成功地运行了约 250 条制作不当的“用户输入”指令,然后丢弃了协程。不幸的是,Java 进程永远不会终止。一个小小的调查表明,由 LuaJ 为协程创建的 LuaThread
将永远存在。
沙盒测试.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
信号结束-但这永远不会发生。我的问题分为两部分:
LuaThread
的引用,我可能能够通过发出 interrupt()
强行放弃它。这是个好主意吗?引用:Lua / Java / LuaJ - Handling or Interrupting Infinite Loops and Threads
编辑:我发布了一个 bug report在 LuaJ SourceForge 上。它讨论了潜在的问题(线程没有像 Lua 规范中那样被垃圾收集)并提出了一些解决它的方法。
最佳答案
这似乎是LuaJ的一个限制。我今年早些时候在 Sourceforge 上提交了一张票据,我看到你也这样做了。 LuaThread
类不存储对其创建的 Java 线程的引用,因此您不能在不修改 LuaJ 核心以公开它们的情况下interrupt()
那些线程:
new Thread(this, "Coroutine-"+(++coroutine_count)).start();
如果不向 LuaJ 添加适当的清理代码就中断这些线程可能很危险。
您为 OrphanedThread
提供的文件还告诉我们范围是定义条件:
“已检测到指示不再引用的 lua 线程的错误子类。抛出此错误的 java 线程应对应于用作协程的 LuaThread,该协程不可能再次恢复,因为 < strong>不再有对其关联的 LuaThread 的引用。 抛出此错误而不是永远锁定资源,并且应该一直落到线程的 Thread.run() 方法。
您的代码示例不会导致所有 LuaThread 引用消失,因此您不应期望抛出异常。 CoroutineLib
文档指出:产生但从未恢复以完成其执行的协程可能不会被垃圾收集器收集
,因此 OutOfMemoryError
实际上应该是预期的 来自 the code you listed on SourceForge , 如果我没错的话。 LuaThread:52
还规定:Applications should not catch OrphanedThread, because it can break the thread safety.
,这是又一个障碍。
在 Lua/J 中,空的和非空的 while
循环似乎也有区别。 IIRC,空循环(while true do end
)不遵守所有协程 Hook /滴答规则。 *因为空循环中没有 Action 发生,所以某些钩子(Hook)没有机会发生(我需要再次测试这个,所以请纠正我!)。
Minecraft 的 ComputerCraft mod 中使用了具有我们正在寻找的功能的 LuaJ 的 fork 版本,尽管它仅为该 mod 设计并且不是开源的。
关于java - 如何放弃 LuaJ 协程 LuaThread?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24585279/
我正在试验一种游戏机制,让玩家可以在游戏内计算机上运行脚本。脚本执行将在游戏级别上受到资源限制,每刻指令数量有限。 以下概念验证演示了基本级别的沙盒和任意用户代码的限制。它成功地运行了约 250 条制
我是一名优秀的程序员,十分优秀!