« 开发笔记(17) : 策划表格公式处理 | 返回首页 | pbc 优化 »

让多个 Lua state 共享一份静态数据

如果你在同一个进程里有多个 lua state , 它们需要共享大量的只读数据, 那么可能就不希望在每个 state 启动的时候都加载和解析一遍这些数据.

所以我们需要一个共享只读数据的方法。

前段时间,我实现了一个 共享内存服务 ,这个可以保证共享内存的安全读写。不过,如果数据是只读的,那么就不需要这么复杂了。

我们只需要把数据加载到一个 lua state 中,其它的同一进程内的 state 通过 C 接口去读数据就可以了。

今天,我做了简单的实现,放在了 github 上。

目前可以支持 nil number boolean function table 的数据交换。

function 交换有一些限制,不可以绑定 upvalue 。是用 string.dump 和 load 实现的。

table 类型返回的其实是一组 key ,需要继续用 get 来读取数据。

关于线程安全:我相信只是读一个 lua state 是线程安全的。

经过 resty 同学提示,由于多线程可能同时改写 database 的 stack ,故而有安全隐患。为了解决这个问题,我预先在 database 的 state 中初始化了 32 个 thread ,这样,不同的 thread 可以用独立的 stack ,应该就线程安全了。


4 月 23 日:

旧的版本, 在企图查询一个不存在的 key 的时候, 由于 lua_pushstring 不能保证线程安全。所以我重写了全部的实现,改用 C 实现了 hash 表。这份实现的读过程是线程安全的。

Comments

这个点说的很实在

不错啊 山西晋鑫来看了看

大侠,看了以后我有个疑惑,求解惑。既然要多个lua_State共享一份数据,为什么不把这些静态数据像加载到一个lua_State* L中,以后创建的lua_State都以L子线程的发生创建,这样不就可以读共享数据了吗?
L1 = lua_newthread(L)我在Lua程序设计那本书上看到的,也写过小例子测试过,不知道这样会不会有什么缺点,望大侠不吝赐教

Thank you for your sharing

我有一个问题。我在一个线程中多次调用Lua函数,是这么写的:
lua_getglobal()
lua_pushnumber()
lua_pushnumber()
lua_pcall()
luaL_checknumber()
luaL_checknumber()
lua_pop(L, 2)
多次调用的时候就会出现内存的分配错误,有时又不会出现该错误。这样的问题究竟怎样解决才好呢?

无聊的时候干什么www.yycc123.com
爱尔眼科医院www.aier0351.com
老万锅炉www.guolu-laowan.com

实在不想等到明天,花了点时间解决了线程安全问题。感觉 OK 了,等明天来测试。

@resty

没错,主要是 stack 的问题。我想想,用 coroutine 模拟出一个线程池, 把 stack 分开应该就可以了。

明天来改。

我觉得这样只读也不是线程安全的。因为这样线程间共用了lua state,而读的时候是要写这个lua state的栈的,这个过程不是原子的,期间很容易出现问题。

好东西,感谢分享。

Post a comment

非这个主题相关的留言请到:留言本