当前位置: 首页 > news >正文

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开口三角电压进行…...

单链表的建立

一.前言 单链表的建立一共有两种方法,一种是头插法,将元素插入在链表的头部,也叫前插法。另外一种则就是尾插法,将元素插入在链表尾部,也叫后插法。 二. 头插法 首先从一个空表开始,重复读入数据&#xff1…...

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比较两个值并返回&#xff1a;true &#xff08;当值相等时&#xff09;|false&#xff08;当值不相等时&#xff09; { $eq: [ <expression1>, <expression2> ] }构造测试数据&#xff1a; db.inventory…...

C语言 | Leetcode C语言题解之第279题完全平方数

题目&#xff1a; 题解&#xff1a; // 判断是否为完全平方数 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中进行图片匹配断言&#xff0c;可以使用OpenCV来实现。以下是使用Appium和OpenCV进行图片匹配断言的示例代码。 首先&#xff0c;需要确保安装了必要的库&#xff1a; pip install opencv-python-headless pip install opencv-python pip install numpy然后&#xf…...

昇思25天学习打卡营第21天|CV-Shufflenet图像分类

打卡 目录 打卡 ShuffleNet 网络介绍 ShuffleNet 模型架构 Pointwise Group Convolution Channel Shuffle ShuffleNet模块 ShuffleNet 模块代码 构建ShuffleNet网络 模块代码 模型训练和评估 模型训练 模型评估 模型预测 ShuffleNet 网络介绍 ShuffleNetV1是旷视科…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...