首页 > 其他分享 >lua/c开发:只读数据共享方案

lua/c开发:只读数据共享方案

时间:2024-03-23 14:22:06浏览次数:30  
标签:方案 lua 只读 VM 数据共享 访问 table 共享

这里只讨论单一进程内的只读数据共享。

同一进程内虚拟内存空间是原本就共享的(以C为例),但在业务开发上,一般会嵌入脚本语言,使用VM的沙盒环境独立维护不同的上下文(以lua为例),多个VM之间(暂时称为业务VM)的数据相互独立。

业务上涉及数据共享的,一般的场景是优化性能、资源占用的情况。需要共享的一般是业务上不变的配置数据或函数原型,每个VM单独维护会带来较大内存浪费、增加gc压力。这里讨论在lua VM之间共享数据的方案。

显然的思路,在业务VM之外单独开启一块内存维护共享的数据,所有业务VM请求获取该数据。

维护这块共享内存,应该要支持:

  1. 线程安全
  2. 不可修改,支持热更新
  3. 优化内存消耗
  4. 访问尽可能高效

这里根据lua的类型分成两部分讨论:函数原型 / table

一. 共享函数原型(lua类型:Proto)

对于lua而言,每个脚本文件load起来都是一个函数。需要解决的问题就是,如何让脚本文件只从IO中加载一次,被需要的VM共享,而不是加载到所有的VM中。

方案:函数原型中的字节码、常量表和调试信息中,对除了常量表和cache之外的部分进行共享。不可共享的部分继承原有的 proto 结构,再用一个指针指向共享部分。改写gc支持Proto类型的引用计数gc策略(实际上保留所有使用过的函数原型不做回收也可以),并由实际load起该函数原型的VM负责进行回收。改写lua的luaL_loadfilex API,使用codecache结构体存放加载的缓存。

二.共享配置数据(lua类型:table)

最简单的方案,将共享数据放在单独的VM中,业务VM访问该公共VM进行获取数据。但VM之间的数据交互相较C层明显高出非常多,性能上不满足。将共享数据存放在redis中的方案也是同理,并且访问redis还需要让出执行权,是异步动作,对进行一次读数据操作这显然是不可接受的。下面讨论几种可行的方案:

方案一:在C层生成唯一的lua table的C对象,全局共享。每个VM使用单独的代理对象进行访问。单次访问代理对象进行一次lua to c 的调用,通过c function 访问到c层的共享数据。

不足点:1)代理对象仍然存在于每个VM中,访问的数据量大时还是带来一定内存开销;
2)通过c function访问c对象,开销仍然比直接访问table大得多。

方案二:仍然在C层生成唯一的C对象,但是规范table中不存在Thread Function Userdata等类型,这样可以做到将Table指针直接返回到lua层使用,而不通过c function访问,需要额外支持gc逻辑使共享表脱离局部虚拟机的管理。

标签:方案,lua,只读,VM,数据共享,访问,table,共享
From: https://www.cnblogs.com/linxx-/p/18091075

相关文章

  • [转帖]Evaluating Garnet's Performance Benefits
    EvaluatingGarnet'sPerformanceBenefitsEvaluatingGarnet'sPerformanceBenefits|Garnet(microsoft.github.io) Wehavetested Garnet thoroughlyinavarietyofdeploymentmodes:SamelocalmachineforclientandserverTwolocalmachines-......
  • 魔兽世界LUA插件开发与示例
    魔兽世界LUA插件开发1.创建插件1.1创建插件文件夹打开WorldofWarcraft\Interface\AddOns文件下,在该文件夹下创建一个插件名文件夹用来存放插件,如Makubex1.2创建插件文件在该文件夹下创建俩个文件,一个是用来给魔兽世界引入的toc头文件,一个是你自己的lua脚本文......
  • 微信小程序(全局数据共享)
       npmi--savemobx-miniprogrammobx-miniprogram-bindings   ......
  • openwrt上使用emmylua + emmyluadebugger + clion调试luci
    lua-emmyluadebuggerAOpenWrtpackageofEmmyLuaDebuggerIntelliJ-EmmyLuaEmmyLuaDebuggerIntelliJ-EmmyLua是一个给JetBrains全家桶用的lua插件,也有VSCode版本VSCode-EmmyLua插件。EmmyLuaDebugger是配合IntelliJ-EmmyLua使用的remotedebugger,C++编写供lua调用的动态......
  • 中文编程入门(Lua5.4.6中文版)第九章 Lua 迭代器 参考种田游戏
    迭代器(iterator)在游戏开发中扮演着重要角色,尤其是在Lua语言中。它是一种特殊的数据结构,能够逐个访问集合中的元素,犹如一位探险家穿越种田游戏的领土,逐一揭示各个城市与资源。在Lua中,迭代器以一种强大的机制实现,它可以跟踪并遍历表或其他集合类型的每一个项目。其中,泛型for循环......
  • Lua 如何在Lua中调用C/C++函数
    Lua调用C函数有两种方式程序主体在C中运行,C函数注册到Lua中。C调用Lua,Lua调用C注册的函数,C或者Lua得到函数的执行结果。程序主体在Lua中运行,C函数作为库函数供Lua使用。C++的代码如下如何在Lua脚本中调用这个C语言函数(add_function)?#include<QCoreApplication>#inclu......
  • Qt 如何搭建Lua的运行环境
    一、Lua简介Lua是一种强大的、高效的、轻量级的、可嵌入的脚本语言。它支持过程(procedural)编程、面向对象编程、函数式编程以及数据描述。Lua是动态类型的,运行速度快,支持自动内存管理,因此被广泛用于配置、脚本编写等场景。二、Lua的优势Lua脚本可以很容易的被C/C++代......
  • Python基础_多进程数据共享
    Python基础_多进程数据共享一、多进程数据共享二、使用multiprocessing.Manager对象三、使用multiprocessing.Value和multiprocessing.Array四、使用管道和队列五、使用共享内存六、注意事项一、多进程数据共享Python中,多进程之间的数据共享是一个复杂的主题,因为每个......
  • Lua中pair和ipair的区别
    Lua中pair和ipair的区别?二者都是Lua中内置的迭代器,可以对数组或table进行遍历。在正常的数组或table的遍历中,二者没有区别。tableNormal={"this","is","a","array"}--使用pairs遍历forkey,valinpairs(tableNormal)doprint(key,'==',val)end遍历结果:--使用......
  • xlua - 增加protobuf库
    lua下常用的2个protobuf库1) GitHub-starwing/lua-protobuf:ALuamoduletoworkwithGoogleprotobuf2) GitHub-cloudwu/pbc:AprotocolbufferslibraryforC这边使用第1个库 a)下载lua-protobuf源码,并解压到xlua的build文件夹根目录 b)CMakeLists.txt中......