簡體   English   中英

我怎么能放棄LuaJ coroutine LuaThread?

[英]How can I abandon a LuaJ coroutine LuaThread?

我正在嘗試一種游戲機制,其中玩家可以在游戲中的計算機上運行腳本。 腳本執行將在游戲級別限制為每個tick的一些指令量。

以下概念驗證演示了任意用戶代碼的沙盒和限制的基本級別。 它成功地運行了大約250條精心設計的“用戶輸入”指令,然后丟棄了協程。 不幸的是,Java進程永遠不會終止。 在顯示了一個小調查,該LuaThread的協同程序創建由LuaJ永遠徘徊。

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 - 處理或中斷無限循環和線程

編輯:我在LuaJ SourceForge上發布了一個錯誤報告 它討論了潛在的問題(線程不像Lua規范那樣被垃圾收集),並提出了一些解決它的方法。

這似乎是LuaJ的限制。 我今年早些時候在Sourceforge上提交了一張票,因為我看到你也做了。 LuaThread類不存儲對它創建的Java線程的引用,因此您不能在不修改LuaJ核心的情況下interrupt()這些線程以暴露它們:

new Thread(this, "Coroutine-"+(++coroutine_count)).start();

在沒有向LuaJ添加適當的清理代碼的情況下中斷這些線程可能是危險的。


您為OrphanedThread提供的文檔還告訴我們范圍是定義條件:

“錯誤sublcass表示已經檢測到不再引用的lua線程。拋出它的java線程應該對應於一個LuaThread,它被用作一個無法再次恢復的協程,因為沒有更多的引用它與之關聯的LuaThread。不是永遠鎖定資源,而是拋出這個錯誤,並且應該一直到線程的Thread.run()方法。“

您的代碼示例不會導致所有LuaThread引用消失,因此您不應該期望拋出異常。 CoroutineLib文檔指出: Coroutines that are yielded but never resumed to complete their execution may not be collected by the garbage collector ,因此如果我沒有弄錯的話,實際上應該從SourceForge上列出的代碼中 預期出現OutOfMemoryError LuaThread:52還指定: Applications should not catch OrphanedThread, because it can break the thread safety of luaj. ,這是另一個障礙。


此外,還似乎是空的和非空之間的差異while在Lua / J環路。 IIRC,空循環( while true do end )不遵守所有協程掛鈎/勾選規則。 *因為在空循環中沒有動作,所以沒有機會發生某些鈎子(我需要再次測試這個,所以請另外糾正我!)。

LuaJ的分叉版本具有我們正在尋找的功能,用於Minecraft的ComputerCraft mod,雖然它僅為mod而設計,並非開源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM