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是旷视科…...

python 图片转文字、语音转文字、文字转语音保存音频并朗读
一、python图片转文字 1、引言 pytesseract是基于Python的OCR工具, 底层使用的是Google的Tesseract-OCR 引擎,支持识别图片中的文字,支持jpeg, png, gif, bmp, tiff等图片格式 2、环境配置 python3.6PIL库安装Google Tesseract OCR 3、安…...

SSRF (服务端请求伪造)
🎼个人主页:金灰 😎作者简介:一名简单的大一学生;易编橙终身成长社群的嘉宾.✨ 专注网络空间安全服务,期待与您的交流分享~ 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持!❤️ 🍊易编橙终身成长社群&#…...

SQL中的LEFT JOIN、RIGHT JOIN和INNER JOIN
在SQL中,JOIN操作是连接两个或多个数据库表,并根据两个表之间的共同列(通常是主键和外键)返回数据的重要方法。其中,LEFT JOIN(左连接)、RIGHT JOIN(右连接)和INNER JOIN…...

[网鼎杯 2020 朱雀组]Nmap(详细解读版)
这道题考察nmap的一些用法,以及escapeshellarg和escapeshellcmd两个函数的绕过,可以看这里PHP escapeshellarg()escapeshellcmd() 之殇 (seebug.org) 两种解题方法: 第一种通过nmap的-iL参数读取扫描一个文件到指定文件中第二种是利用nmap的参数写入we…...

【React】详解“最新”和“最热”切换与排序
文章目录 一、基本概念和初始化二、切换与排序功能的实现1. 函数定义和参数2. 设置活动 Tab3. 定义新列表变量4. 根据排序类型处理列表4.1 按时间降序排序4.2 按点赞数降序排序 5. 更新评论列表 三、渲染导航 Tab 和评论列表1. map 方法2. key 属性3. className 动态赋值4. onC…...

BUUCTF [MRCTF2020]Ezpop
这道题对于刚接触到pop链的我直接把我整懵了,一边看着魔术方法一边分析 魔术方法可以看这里PHP 魔术方法 - 简介 - PHP 魔术方法 - 简单教程,简单编程 (twle.cn) 代码解析 经过以上的分析我们可以理一下解题思路:接收参数反序列化之前先触发…...

RV1126 Linux 系统,接外设,时好时坏(一)应该从哪些方面排查问题
在 Linux 系统中接外设时,遇到“时好时坏”的问题,可能是由多种因素引起的。以下是一些排查问题的建议。 1. 硬件方面的排查 1.1 连接检查 物理连接: 确保外设与主板之间的连接良好,检查插头、插座及线缆是否牢固。引脚配置: 确认设备树中引脚的配置是否正确,尤其是引脚…...

Vue实现简单小案例
一、创建文件夹 二、引用vue.js <script src"../js/vue.js"></script> 三、准备一个容器 <div id"app"><h1>Hello,{{name}}</h1> </div> 四、创建实例 <script>new Vue({el:"#app", //el用于指…...

【MATLAB APP】建立独立桌面APP
背景:已有MATLAB APP的.mlapp文件,但客户提出需要可以直接使用的exe文件。 要求:点开即用,无需下载MATLAB。使用者无法修改APP的代码。 一、环境配置 APP创建者:安装MATLAB R2023a,配置Application Compile…...

Spring的优缺点?
Spring的优缺点 直接回答相关的Spring的特点: IOC AOP 事务 简化开发: 容易集成JDBCTemplateRestTemplate(接口远程调用)邮件发送相关异步消息请求支持 更加深入就讲源码了 优点: 方便解耦,简化开发…...