5

tl;dr バージョン: グローバル変数にアクセスする場合、Lua 状態のシャットダウン中にガベージ コレクション メタメソッドは安全ですか? ローカルのアップ値はどうですか?


lua_Stateで閉じられるとlua_close、Lua のドキュメントには、すべてのオブジェクトが削除されると書かれています。また、関連するガベージ コレクション メタメソッドが呼び出されることが保証されていることも示しています。

偉大な。

ただし、このパラダイムでは不明な GC メタメソッドの使用例が 2 つあります。

  1. 収集可能な値を格納するローカル変数を使用する GC メタメソッドがある場合はどうでしょう。たとえば、文字列、関数などです。つまり、GC メタメソッドは次のように定義されます。

    local some_string = "string"
    function mt:__gc() --[[Do something with some_string]] end
    

    この場合はどうなりますか?some_string回収は可能ですか?メタテーブルがあるオブジェクトが通常の状況で収集されている場合、これは不可能であることはわかっています。some_stringLua は、GC 関数自体が収集されるまでの値が保持されることを保証します。

    しかし、すべてのオブジェクトが によって破棄されているlua_closeため、関数が破棄される前に GC 関数の上位値が破棄される可能性はありますか? (これはあらゆる種類の問題を引き起こす可能性があるため) そうではないと思いますが、私が考えていることではなく、本当の答えを探しています。

  2. GC メタメソッドで多くの問題が発生するため、#1 が問題になる可能性は低いことを認めます。ただし、これはまったく別の問題です。

    local some_string = "string"
    function mt:__gc() print(some_string) end
    

    これは#1のように見えますが、そうではありません。なんで?グローバル変数にアクセスするためです。つまり、print.

    関数と格納されている値との間には直接的な関連はありませんprint(ケース 1 とは異なり、some_stringは明らかに関数の上位値です)。そのため、printLua 状態のシャットダウン中に関数を呼び出す前に が収集される可能性があります。

問題はこれです:ガベージ コレクション メタメソッドが、 Lua 状態のシャットダウン中にグローバル テーブルから何かを使用することは安全ですか ( に対してグローバル テーブルの意図的な妨害行為の可能性を無視します)。print = nilそれとも、原則として、それらが触れる関数やデータを常に明示的にローカルにする必要がありますか? 問題を回避するのに十分でしょうか?

4

1 に答える 1

4

メソッドからアクセスできるデータはすべて__gc安全にアクセスできます。これには、 を含む など、アクセス可能なローカルとテーブルの両方_Gが含まれますprint

問題になる可能性があるのは、(アンロードされた) C ライブラリです。これは Lua 5.1 に影響し、Lua 5.2.1 で修正されています。「ファイナライザーは、ライブラリーがアンロードされた後、動的ライブラリーから関数を呼び出す可能性があります」のパッチを参照してください。

于 2012-08-11T01:51:32.090 に答える