gpt4 book ai didi

java - 如何放弃 LuaJ 协程 LuaThread?

转载 作者:搜寻专家 更新时间:2023-11-01 03:05:22 25 4
gpt4 key购买 nike

我正在试验一种游戏机制,让玩家可以在游戏内计算机上运行脚本。脚本执行将在游戏级别上受到资源限制,每刻指令数量有限。

以下概念验证演示了基本级别的沙盒和任意用户代码的限制。它成功地运行了约 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 信号结束-但这永远不会发生。我的问题分为两部分:

  • 我是不是做了什么根本性的错误导致了这种行为?
  • 如果不是,我应该如何处理这种情况?从源代码看来,如果我能在 Java 中获得对 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com