Правила о выключении состояния Lua и метаметодах сборки мусора

Версия tl; dr :является безопасным метаметодом сборки мусора во время выключения состояния Lua, если он обращается к глобальным переменным? Как насчет локальных значений up -?


Когда lua_Stateзакрывается с помощью lua_close, в документации Lua говорится, что все объекты удаляются . И это говорит о том, что любые ассоциированные метаметоды сборки мусора -гарантированно будут вызываться.

Отлично.

Однако есть два возможных варианта использования метаметодов сборщика мусора, которые в этой парадигме неясны:

  1. Что делать, если у вас есть метаметод GC, который использует локальную переменную, в которой хранится собираемое значение. Скажем, строка, функция и т. д. То есть ваш метаметод GC определяется как:

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

    Что происходит в этом случае? Можно ли собрать some_string? Я знаю, что если объект, на котором находится метатаблица, собирается при нормальных обстоятельствах, то это невозможно. Lua гарантирует, что значение some_stringостанется до тех пор, пока не будет собрана сама функция GC.

    Но поскольку все объекты уничтожаются с помощью lua_close, возможно ли, что верхние значения функции GC могут быть уничтожены до того, как будет уничтожена сама функция? Я не думаю, что это (, так как это может вызвать всевозможные проблемы ), но я ищу реальный ответ, а не то, что я думаю.

  2. Я признаю, что маловероятно, что #1 будет проблемой, так как это создаст много проблем с метаметодами сборщика мусора. Однако это совсем другое дело:

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

    Это выглядит как #1, но это не так. Почему? Потому что он обращается к глобальной переменной . А именно print.

    Нет прямой связи между функцией и любым значением, хранящимся в print(. в отличие от случая 1,где some_stringявно является верхним значением функции ). Таким образом, printможно собрать перед вызовом функции во время выключения состояния Lua.

Вопрос в том, :является ли безопасным для метаметода сборки мусора когда-либо использовать что-либо из глобальной таблицы (, игнорируя возможность преднамеренного саботажа глобальной таблицы по отношению -к -висprint = nil)во время выключения состояния Lua? Или, как правило, они должны всегда явно делать любые функции или данные, к которым они прикасаются, локальными? Будет ли этого достаточно, чтобы избежать проблем?

5
задан Nicol Bolas 10 August 2012 в 18:24
поделиться