Lua编程
文章目录
- 概述
- lua数据类型
- 元表
- 注意
- 闭包
- 表现
- 实现
- lua/c 接口编程
- skynet中调用层次
- 虚拟栈
- C闭包
- 注册表
- userdata
- lightuserdata
- 小结
概述
这次是skynet,需要一些lua/c相关的。写一篇博客,记录下。希望有所收获。
lua数据类型
- boolean , number , string , nil , function , table , userdata , lightuserdata , thread ;
boolean 为 true 、 false ;其中 false 可以解决 table 作为 array 时,元素为 nil 时造成
table 取长度未定义的行为; - number 为 integer 和 double 的总称;
- string 常量字符串;这样 lua 中字符串比较只需要进行地址比较就行了;
- nil 通常表示未定义或者不存在两种语义;
- function 函数;与其他语言不同的是,lua 中 function 为第一类型;注意 lua 中的匿名函
数,lua 文件可视为一个匿名函数;加载 lua 文件,可视为执行该匿名函数; - table 表;lua 中唯一的数据结构;既可以表示 hashtable 也可表示为 array;配合元表可以定制
表复杂的功能(如实现面对对象编程中的类以及相应继承的功能); - userdata 完全用户数据;指向一块内存的指针,通过为 userdata 设置元表,lua 层可以使用
该 userdata 提供的功能; userdata 为 lua 补充了数据结构,解决了 lua 数据结构单一的问
题;可以在 c 中实现复杂的数据结构,生成库继而导出给 lua 使用;注意: userdata 指向的内存
需要由 lua 创建,同时 userdata 的销毁也交由 lua gc 来自动回收; - lightuserdata 轻量用户数据;也是指向一块内存的指针,但是该内存由 c 创建,同时它的销毁
也由 c 来完成;不能为它创建元表,轻量用户数据只有类型元表;通常用于 lua 想使用 c 的结构,但是不能让 lua 来释放的结构;在游戏客户端中用的比较多; - thread 线程;lua 中的协程和虚拟机都是 thread 类型;
元表
常用的有:
- __index :索引 table[key] 。 当 table 不是表或是表 table 中不存在 key 这个键时,这个
事件被触发。 此时,会读出 table 相应的元方法。 - __newindex :索引赋值 table[key] = value 。 和索引事件类似,它发生在 table 不是表或
是表 table 中不存在 key 这个键的时候。 此时,会读出 table 相应的元方法。 - __gc :元表中用一个以字符串 " __gc " 为索引的域,那么就标记了这个对象需要触发终结器;
这些常用,是语言层次的,不区分客户端,服务器。
注意
- 只有 table 和 userdata 对象有独自的元表,其他类型只有类型元表;
- 只有 table 可以在 lua 中修改设置元表;
- userdata 只能在 c 中修改设置元表,lua 中不能修改 userdata 元表;
闭包
表现
- 函数内部可以访问函数外部的变量;
- lua 文件是一个匿名函数;
lua内部函数可以访问文件中函数体外的变量;
实现
- C 函数以及绑定在 C 函数上的上值(upvalues);
lua/c 接口编程
skynet、openresty 都是深度使用 lua 语言的典范;学习 lua 不仅仅要学习基本用法,还要学会使
用 c 与 lua 交互,这样才学会了 lua 作为胶水语言的精髓;
skynet中调用层次
虚拟栈
- 栈中只能存放 lua 类型的值,如果想用 c 的类型存储在栈中,需要将 c 类型转换为 lua 类型;
- lua 调用 c 的函数都得到一个新的栈,独立于之前的栈;
- c 调用 lua,每一个协程都有一个栈;
- c 创建虚拟机时,伴随创建了一个主协程,默认创建一个虚拟栈;
- 无论何时 Lua 调用 C , 它都只保证至少有 LUA_MINSTACK 这么多的堆栈空间可以使用。
LUA_MINSTACK 一般被定义为 20 , 因此,只要你不是不断的把数据压栈, 通常你不用关心堆栈大小。
C闭包
- 通过 lua_pushcclosure 用来创建 C 闭包;
- 通过 lua_upvalueindex 伪索引来获取上值(lua 值);
- 可以为多个导出函数(c 导出函数给 lua 使用)共享上值,这样可以少传递一个参数;
注册表
可以用来在多个 c 库中共享 lua 数据(包括 userdata 和 lightuserdata );
- 一张预定义的表,用来保存任何 c 代码想保存的 lua 值;
- 使用 LUA_REGISTRYINDEX 来索引;
userdata
- userdata 是指向一块内存的指针,该内存由 lua 来创建,通过 void
*lua_newuserdatauv(lua_State *L, size_t sz, int nuvalue) 这个函数来创建;注意:这
块内存大小必须是固定的,不能动态增加,但是这块内存中的指针指向的数据可以动态增加;还有
就是 userdata 可以绑定若干个 lua 值(又称uservalue)(在 lua 5.3 中只能绑定一个 lua 值,
lua 5.4 可以绑定多个); userdata 与 uservalue 的关系是引用关系,也就是 uservalue 的生命周
期与 userdata 的生命周期一致, userdata gc 时,uservalue 也会被释放;通常这个特性可以
用来绑定一个 lua table 结构,因为 c 中没有 hash 结构,辅助 lua table 结构实现复杂的功
能;也可以用来实现延迟 gc,如果某个 userdata 希望晚点 gc,在 userdata 的 __gc 元表中
生成一个临时的 userdata ,然后将那个希望晚点 gc 的 userdata 绑定在这个临时 userdata
的 uservalue 上; - int lua_getiuservalue (lua_State *L, int idx, int n) 来获取绑定在 userdata 上的
uservalue; - int lua_setiuservalue (lua_State *L, int idx, int n) 来设置 userdata 上的
uservalue;
lightuserdata
轻量用户数据也是指向一块内存的指针,但是该内存由 c 来创建和销毁;通常这块内存的生命周期
由 c 宿主语言来控制;可以将 lightuserdata 绑定在注册表中,让多个 lua 库共享该数据;在
skynet 中, lightuserdata 可以指向同一块数据,在多个 Actor 中传递这个 lightuserdata ,
然后分别为这个 lightuserdata 创建一个 userdata ; 在 userdata 中的 __gc 来释放这个
lightuserdata ;注意:为了避免这块内存多次释放,需要为这块内存加上引用计数;同时
skynet 中 actor 是多线程环境下运行,所以需要为该 lightuserdata 加上锁;这个锁必须是自
旋锁或者原子操作,因为 actor 调度是自旋锁,必须使用比它更小的粒度的锁;如果
lightuserdata 操作粒度过大,应该改成只在一个 actor 中加载,其他 actor 通过消息来共享数
据;
小结
这一篇lua编程不同于之前的lua源码阅读,写那一篇的时候,主要是在写一些源码中的内容;这一篇,包括各种数据结构,c,以及lua的。感兴趣,都可以看看,也可以一起学习学习。OK,这篇结束。
相关文章:

Lua编程
文章目录 概述lua数据类型元表注意 闭包表现 实现 lua/c 接口编程skynet中调用层次虚拟栈C闭包注册表userdatalightuserdata 小结 概述 这次是skynet,需要一些lua/c相关的。写一篇博客,记录下。希望有所收获。 lua数据类型 boolean , number , string…...

2019数字经济公测大赛-VMware逃逸
文章目录 环境搭建漏洞点exp 环境搭建 ubuntu :18.04.01vmware: VMware-Workstation-Full-15.5.0-14665864.x86_64.bundle 这里环境搭不成功。。patch过后就报错,不知道咋搞 发现可能是IDA加载后的patch似乎不行对原来的patch可能有影响,重新下了patch&…...

如何改桥接模式
桥接模式主要是解决 路由功能的 因为NAT多层 主要是网络连接数太多时 然后路由器要好 不然光猫 比差路由要强的 光猫 请注意,对光猫的任何设置进行修改前,请一定要备份光猫的配置文件,并在每次修改前都截图保存原始设置信息!不要…...

江科大/江协科技 STM32学习笔记P13
文章目录 TIM定时中断1、TIM简介计数器PSC预分频器ARR自动重装寄存器 2、定时器类型基本定时器主模式触发DAC 通用定时器高级定时器 3、定时器原理定时中断基本结构预分频器时序计数器时序RCC时钟树 TIM定时中断 1、TIM简介 定时器的基准时钟一般都是主频72MHz,如果…...
loadrunner录制解决提示安全问题
点击页面任意位置,输入: thisisunsafe...

为什么要读写分离?如何实现业务系统读写分离?
信息化水平提升,很多企业已经接受并高频使用多样的业务系统进行日常作业,而在不断的使用过程中,部分行业和业务,如:直播电商、基础制造、公关传媒等,由于自身特点的原因,常常积累了海量的数据。…...

C#基础——类、构造函数和静态成员
类 类是一个数据类型的蓝图。构成类的方法和变量称为类的成员,对象是类的实例。类的定义规定了类的对象由什么组成及在这个对象上可执行什么操作。 class 类名 { (访问属性) 成员变量; (访问属性) 成员函数; } 访问属性:public(公有的&…...

hadoop学习(二)
一.MapReduce 1.1定义:是一个分布式运算程序的编程框架 1.2核心功能:将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上。 1.3优点 1)易于编程 它简单的实现一些接口&#…...
WXZ196微机消谐装置的运行方式了解一下
WXZ196微机消谐装置是一种用于抑制铁磁谐振的设备,可以在电力系统中快速消除各种频率的铁磁谐振,同时可以区分过电压、铁磁谐振以及单相接地,并给出相应的报警信号。该装置采用高速增强型单片机作为核心元件,对PT开口三角电压进行…...
单链表的建立
一.前言 单链表的建立一共有两种方法,一种是头插法,将元素插入在链表的头部,也叫前插法。另外一种则就是尾插法,将元素插入在链表尾部,也叫后插法。 二. 头插法 首先从一个空表开始,重复读入数据࿱…...

Shell脚本编程学习
IPv4和IPv6有什么区别? - 知乎 (zhihu.com) Shell 是一个命令解释权,它为用户提供了一个向 Linux 内核发送请求以便运行程序界面系统级程序,用户可以用 Shell 来启动、挂起、停止甚至是编写一些程序。 可以查看当前系统的进程 ps -ef...

从宏基因组量化细菌生长动态
Introduciton 了解细菌在各种环境中的生长动态对于人类健康和环境监测等广泛领域至关重要。传统研究细菌生长的方法往往依赖于培养技术,这不仅耗时,而且对易培养的物种有偏向。然而,随着宏基因组测序技术的兴起,我们现在可以直接…...

Linux---git工具
目录 初步了解 基本原理 基本用法 安装git 拉取远端仓库 提交三板斧 1、添加到缓存区 2、提交到本地仓库 3、提交到远端 其他指令补充 多人协作管理 windows用户提交文件 Linux用户提交文件 初步了解 在Linux中,git是一个指令,可以帮助我们做…...

【JavaScript】函数的动态传参
Javacript(简称“JS”)是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中,JavaScript基于原型编程、多范式的动态脚本语言&…...

从0到1,AI我来了- (4)AI图片识别的理论知识-II
上篇文章,我们理解了我们程序的神经网络设计,这篇我们继续,把训练迭代过程分析一下,完成这两篇文章,下面问题,应该能回答了。 一张图片,如何被计算机读懂?pytorch 封装的网络&#…...

2024 Java 高分面试宝典 一站式搞定技术面
前言 每年9月和10月,被业界称为“金九银十”,这是人才市场一年中最活跃的时期。此时,企业为了来年的业务扩展,纷纷加大招聘力度,空缺岗位众多,招聘需求集中。同时,初秋的招聘活动也避开酷暑&am…...
MongoDB - 聚合操作符 $eq、$gte、$in、$sum、$avg
文章目录 1. $eq2. $gte3. $in4. $sum5. $avg 1. $eq $eq比较两个值并返回:true (当值相等时)|false(当值不相等时) { $eq: [ <expression1>, <expression2> ] }构造测试数据: db.inventory…...

C语言 | Leetcode C语言题解之第279题完全平方数
题目: 题解: // 判断是否为完全平方数 bool isPerfectSquare(int x) {int y sqrt(x);return y * y x; }// 判断是否能表示为 4^k*(8m7) bool checkAnswer4(int x) {while (x % 4 0) {x / 4;}return x % 8 7; }int numSquares(int n) {if (isPerfect…...
在appium中,如何通过匹配图片来进行断言?
在Appium中进行图片匹配断言,可以使用OpenCV来实现。以下是使用Appium和OpenCV进行图片匹配断言的示例代码。 首先,需要确保安装了必要的库: pip install opencv-python-headless pip install opencv-python pip install numpy然后…...

昇思25天学习打卡营第21天|CV-Shufflenet图像分类
打卡 目录 打卡 ShuffleNet 网络介绍 ShuffleNet 模型架构 Pointwise Group Convolution Channel Shuffle ShuffleNet模块 ShuffleNet 模块代码 构建ShuffleNet网络 模块代码 模型训练和评估 模型训练 模型评估 模型预测 ShuffleNet 网络介绍 ShuffleNetV1是旷视科…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...

面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...