加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Lua(LuaJit)和C中的对象生命周期

发布时间:2020-12-14 21:43:46 所属栏目:大数据 来源:网络整理
导读:我使用LuaJit扩展普通的C应用程序(使用Lua C API).主机应用程序确实为我在Lua中编写包装器的许多对象管理内存. 现在我希望能够从lua函数中删除对象,即实现删除功能.我想用下面的问题大纲说明手头的问题. 基本上我的lua用户数据结构看起来像这样. struct my_l
我使用LuaJit扩展普通的C应用程序(使用Lua C API).主机应用程序确实为我在Lua中编写包装器的许多对象管理内存.

现在我希望能够从lua函数中删除对象,即实现删除功能.我想用下面的问题大纲说明手头的问题.

基本上我的lua用户数据结构看起来像这样.

struct my_lua_container {
     size_t obj_db_index;
};

其中obj_db_index是本地对象数据库的索引.使用Lua C API,我创建了一个lua-function query_object(…),它根据此用户数据检索lua metatable,并提供用于管理db对象的API.

我现在计划在metatable API中引入一个方法my_db_object:delete(). :delete()可以通过用0覆盖变量或设置另一个成员变量来使my_db_object无效.但问题是,对删除的对象的所有引用都应该是无效的.考虑一下这个lua代码:

local p = query_object("1")
local q = query_object("1")
p:delete()
q:do_something() -- <=== q still contains a obj_db_index

现在我想知道如何解决这个潜在的冲突.两个主要问题是:

>无效的obj_db_index可能是无效索引.这实际上可能已经被代码捕获了,所以它不是很好但是没问题
>删除后,索引可能会被重用,当其他引用仍然使用旧索引时,这可能会导致细微的错误.

有什么策略可以解决这个问题?

我的想法可能有点耗时,但如果删除就可以了:

>我可以对用户数据对象执行一些内省吗?就像迭代所有具有相同类型的用户数据对象一样,以便在触发删除时使my_db_index无效

解决方法

也许有点晚了,但是…解决方案是将新对象放入弱表中,永远不会创建已经存储在那里的对象.

-- this should be really C,but for readability,we write it in Lua pseudocode
registry.my_cache = setmetatable({ },{ __mode = "v" })

function push_object(db_id)
    local object = registry.my_cache[db_id]
    if object == nil then
        object = lua_newuserdata(db_id)
        registry.my_cache[db_id] = object
    end
end

assert(push_object(1) == push_object(1))

现在只有唯一的db_id从C侧到Lua侧,问题几乎消失了.

但还有一个细节可以照顾. userdata的垃圾收集有两个阶段:完成和从弱表中删除.有些时候,当userdata最终确定但仍存在于弱表中时,因此上面的代码可能会将最终的用户数据返回给用户.应进行额外检查,如果最终确定,应首先从表中手动删除.

function push_object(db_id)
    local object = registry.my_cache[db_id]

    -- check vitality first
    if is_finalized(object) then
        registry.my_cache[db_id] = nil
        object = nil
    end

    if object == nil then
        object = lua_newuserdata(db_id)
        registry.my_cache[db_id] = object
    end
end

您如何知道userdata是否已最终确定取决于您的终结方法(metatable .__ gc)的实现.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读