skynet学习笔记 sharetable共享表

sharetable特点

1.不同虚拟机共享

2.不可更改

3.脱落gc

4.不可以设置元表

适用场景

不同虚拟机都需要用到的不在代码内更改的配置表

API

sharetable.loadfile(filename,...)

通过文件加载一个lua表,云风大佬推荐使用api

sharetable.loadstring(str)

类似loadfile,loadfile多了一步读取文件

sharetable.loadtable(tbl)

直接共享一张表,云风大佬不推荐,因为此接口会经过一次序列化和拷贝

sharetable.query(filename)

查询共享table

sharetable.update(...)

更新一个或多个key

sharetable.queryall()

查询多个共享表

sharetable更新

sharetable多次load同一张表时会生成多份表数据,只不过query查询永远指向以filename为key的最新加载的数据表地址,所以当你重新loadfile的时候,之前query过的虚拟机指向的是老的filename地址,需要调用sharetable.update更新一下。

sharetable释放

当一个filename被加载多次,老的数据表应该释放,那么何时释放?

sharetable对于每一个数据表都标记了引用计数,当一个虚拟机查询拿到了这个数据表,会使引用计数加1,只有引用计数为0并且不是最新的数据表,才会被释放掉。

    local function query_file(source, filename)local m = files[filename]local ptr = m:getptr()local ref = matrix[ptr]if ref == nil thenref = {filename = filename,count = 0,matrix = m,refs = {},}matrix[ptr] = refendif ref.refs[source] == nil thenref.refs[source] = truelocal list = clients[source]if not list thenclients[source] = { ptr }elsetable.insert(list, ptr)endref.count = ref.count + 1endreturn ptrendfunction sharetable.close(source)local list = clients[source]if list thenfor _, ptr in ipairs(list) dolocal ref = matrix[ptr]if ref and ref.refs[source] thenref.refs[source] = nilref.count = ref.count - 1if ref.count == 0 thenif files[ref.filename] ~= ref.matrix then-- It's a history versionskynet.error(string.format("Delete a version (%s) of %s", ptr, ref.filename))ref.matrix:close()matrix[ptr] = nilendendendendclients[source] = nilend-- no returnend

何时才能释放引用,需要虚拟机退出,也就是引用过数据表的虚拟机调用skynet.exit()退出了,才能释放引用计数。

local function report_close(t)local addr = rawget(t, "address")if addr thenskynet.send(addr, "lua", "close")end
endlocal sharetable = setmetatable ( {} , {__index = load_service,__gc = report_close,
})

云风大佬是妙用的__gc原方法的方式调用发送close消息给sharetable,释放掉改虚拟机所以的引用。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部