loadfile加载pb文件后好像没释放资源导致崩溃
lua 5.3.4 ubuntu 22 下载代码并生成pb.so,我服务器的skynet的agent服务,lua代码加载pb模块,然后pb去loadfile XXX.pb文件后能解析protobuf协议,但是agent退出时导致主进程崩溃,屏蔽了loadfile之后,agent退出就没问题,这个pb是不是需要释放资源?
可以看看这个 https://github.com/cloudfreexiao/lua-protobuf
可以看看这个 https://github.com/cloudfreexiao/lua-protobuf
请教下,我不太明白,那问题的关键是从哪里入手处理呢
可以看看这个 https://github.com/cloudfreexiao/lua-protobuf
请教下,我不太明白,那问题的关键是从哪里入手处理呢
你diff一下,没改多少。
可以看看这个 https://github.com/cloudfreexiao/lua-protobuf
请教下,我不太明白,那问题的关键是从哪里入手处理呢
你diff一下,没改多少。
提一个pr?
lua 5.3.4
ubuntu 22
下载代码并生成pb.so,我服务器的skynet的agent服务,lua代码加载pb模块,然后pb去loadfile XXX.pb文件后能解析protobuf协议,但是agent退出时导致主进程崩溃,屏蔽了loadfile之后,agent退出就没问题,这个pb是不是需要释放资源?
另外能给一个崩溃的堆栈吗?理论上这个库应该单线程使用,如果有多个Lua状态也是可以的,但是如果你多线程使用了同一个状态那可能的确会有点问题,具体情况要看堆栈。不过多线程其实也能用,你要看看unsafe模块,它提供了“多个状态共享载入数据”的功能。
@cloudfreexiao 你来提个pr?
没用过 unsafe 相关的 接口 目前的做法是让整个进程只加载一次的同时再标记成共享保证只有一个的lua state 改完之后相关的 test_unsafe 测试用例会不通过
https://github.com/cloudfreexiao/lua-protobuf/tree/pr
lua 5.3.4 ubuntu 22 下载代码并生成pb.so,我服务器的skynet的agent服务,lua代码加载pb模块,然后pb去loadfile XXX.pb文件后能解析protobuf协议,但是agent退出时导致主进程崩溃,屏蔽了loadfile之后,agent退出就没问题,这个pb是不是需要释放资源?
可以贴一下你的代码吗?我想实验一下
https://github.com/cloudfreexiao/lua-protobuf/tree/pr @cloudfreexiao @hanxi 你好,这个分支,skynet 多个服务同时使用是安全的吗,现在我们每个服务都去加载protobuf的pb文件,导致cmem会占1.7M。我刚刚试了下这个可以用,如果是安全的,会给我们节省很多内存。如果可以用,那效率不知道和不共享lua state,会不会有差别
https://github.com/cloudfreexiao/lua-protobuf/tree/pr @cloudfreexiao @hanxi 你好,这个分支,skynet 多个服务同时使用是安全的吗,现在我们每个服务都去加载protobuf的pb文件,导致cmem会占1.7M。我刚刚试了下这个可以用,如果是安全的,会给我们节省很多内存。如果可以用,那效率不知道和不共享lua state,会不会有差别
你好,官方目前已经支持了全局的state,具体请看pb.state()函数。另外unsafe.use "global"允许你使用“上次成功load协议”的State。你可以在代码里搜索global_state看看实现(共7个地方)。如果这个功能在skynet有bug,请提交issue,我来修。
@starwing 程序启动时 local protobuf = require "pb" protobuf.loadfile() ,加载了一批pb文件
然后调用
local protobuf_unsafe = require "pb.unsafe"
protobuf_unsafe.use("global")
后面的新建服务使用 local protobuf = require "pb" protobuf.decode和protobuf.encode
这样报|exceptionUtil.lua:33:unknown| bad argument #1 to 'pb.decode' (type 'DB.million' does not exists)
@starwing 程序启动时 local protobuf = require "pb" protobuf.loadfile() ,加载了一批pb文件
然后调用 local protobuf_unsafe = require "pb.unsafe" protobuf_unsafe.use("global")
后面的新建服务使用 local protobuf = require "pb" protobuf.decode和protobuf.encode
这样报|exceptionUtil.lua:33:unknown| bad argument #1 to 'pb.decode' (type 'DB.million' does not exists)
你用错了。单线程的时候一个Lua实例loadfile,然后注意这个Lua实例不能卸载。然后多线程的时候先require "pb"再unsafe.use "global",然后就可以pb.decode了。
loadfile的那个虚拟机什么都不用做,多线程环境下的虚拟机每一个都必须调用unsafe.use。明白了吗?
@starwing 嗯,现在可以了。查了下 共享时 const pb_State *state; 这个只在加载时赋值,后续不会修改,其他好像都是每个状态机自己的,按理是没有多线程问题
@uiuizz 对,这个接口就是为skynet做的。之所以放进unsafe里是因为如果loadfile的那个状态机销毁了,后续其他状态机可能访问释放内存导致崩溃。你需要自己保证loadfile状态机存活。