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,这篇结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/876783.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大模型算法面试题(十五)

本系列收纳各种大模型面试题及答案。 1、大模型LLM进行SFT如何对样本进行优化 大模型LLM(Language Model,语言模型)进行SFT(Structured Fine-Tuning,结构化微调)时,对样本的优化是提升模型性能…

Linux源码阅读笔记16-文件系统关联及字符设备操作

文件系统关联 设备文件都是由标准函数处理,类似普通文件。设备文件也是通过虚拟文件系统来管理的,和普通文件都是通过完全相同的接口访问的。 inode中设备文件的成员数据 虚拟文件系统每个文件都关联到一个inode,用于管理文件的属性。源码如…

【Go - context 速览,场景与用法】

作用 context字面意思上下文,用于关联管理上下文,具体有如下几个作用 取消信号传递:可以用来传递取消信号,让一个正在执行的函数知道它应该提前终止。超时控制:可以设定一个超时时间,自动取消超过执行时间…

Swift学习入门,新手小白看过来

😄作者简介: 小曾同学.com,一个致力于测试开发的博主⛽️,主要职责:测试开发、CI/CD 如果文章知识点有错误的地方,还请大家指正,让我们一起学习,一起进步。 😊 座右铭:不…

(十三)Spring教程——依赖注入之工厂方法注入

1.工厂方法注入 工厂方法是在应用中被经常使用的设计模式,它也是控制反转和单例设计思想的主要实现方法。由于Spring IoC容器以框架的方式提供工厂方法的功能,并以透明的方式开放给开发者,所以很少需要手工编写基于工厂方法的类。正是因为工厂…

如何从网站获取表格数据

1.手动复制粘贴 最简单的方法是直接在网页上手动选择表格内容,然后复制粘贴到Excel或其他表格处理软件中。这种方法适用于表格较小且不经常更新的情况。 2.使用浏览器插件 有许多浏览器插件可以帮助从网页中提取表格数据,例如: -TableCapt…

SSRF过滤攻击

SSRF绕过: 靶场地址:重庆橙子科技SSRF靶场 这个是毫无过滤的直接读取,但是一般网站会设置有对SSRF的过滤,比如将IP地址过滤。 下面是常用的绕过方式: 1.环回地址绕过 http://127.0.0.1/flag.php http://017700…

相机怎么选(不推荐,只分析)

title: 相机怎么选 tags: [相机, 单反相机] categories: [其他, 相机] 最近准备购买,相机怎么选,我去搜索了许多文章,整理了一篇小白挑选技术篇,供大家参考。 分类 胶片相机 需要装入胶卷才能使用的相机,拍照后可直…

永磁同步电机无速度算法--非线性磁链观测器

非线性磁链观测器顾名思义观测器的状态变量为磁链值,观测的磁链值收敛于电机实际磁链值,观测器收敛。非线性是由于观测器存在sin和cos项,所以是非线性观测器 一、原理介绍 表贴式永磁同步电机αβ轴电压方程: 将公式变换 定义状态变量X: 定…

Milvus 向量数据库进阶系列丨部署形态选型

本系列文章介绍 在和社区小伙伴们交流的过程中,我们发现大家最关心的问题从来不是某个具体的功能如何使用,而是面对一个具体的实战场景时,如何选择合适的向量数据库解决方案或最优的功能组合。在 “Milvus 向量数据库进阶” 这个系列文章中&…

Java实现打印功能

JPG图片文件格式打印实现 打印JPG图片格式的文件,本次采用的Java原生的打印方式。 public static void main(String[] argv) throws Exception {File file new File("E:\\a.jpg");String printerName "HP MFP M436 PCL6";//打印机名包含字串…

vite+vue3项目,开发时候正常,打包后router-view不渲染

这是个很奇怪的问题,但是基本上命名或者引入文件的方式导致的。要么文件名与系统的某些标签名一样,要么就是routes写成了routers。还有一种就是导入方式错误的 错误截图: 正确引入截图:

Flink大状态作业调优——DataStream篇

一、Flink 状态(State)简介 在流式计算中有些操作一次处理一个独立的事件(比如解析一个事件), 有些操作却需要记住多个事件的信息(比如窗口操作)。那些需要记住多个事件信息的操作就是有状态的。流式计算分为无状态计算和有状态计算两种情况。状态可以理…

Word题库转Excel关键字快速查询题库

一、前言 内部培训会有Word版本题库,考核时如果使用Word、Excel、PDF等文档进行关键字查询题目体验不佳。so,撸个软件吧!   20240728更新:支持更多题库类型。 二、Word题库转Excel 1、Word题库格式要求 内容格式要求事例题目…

在 Postman 中设置全局 token

目录 问题描述解决方案 问题描述 在使用 Postman 进行接口测试时,经常会遇到在 Header 中添加 token 的情况。当接口数量较多时,需要为每个接口进行设置,而且当 token 失效时需要重新获取并设置,这样一来效率较低。 解决方案 下…

wpf中开发独立模块功能和左侧1个菜单的框架演示

此篇文章适用于有一定经验的wpf开发者,并且是团队协作开发模式,并且业务与此比较相近的话,用起来非常的方便。 我们在开发wpf程序的时候,比如1,2个人,那肯定随便怎么开发,都没事,代码…

Matlab M_map工具箱绘制Interrupted Mollweide Projection

GMT自带了许多的地图投影,但是对于Interrupted Mollweide投影效果却不好。 作为平替的m_map工具箱中带有的投影类型可完美解决这一问题。 Interrupted Mollweide Projection长这样 全球陆地 全球海洋 使用Matlab工具箱m_map展示全球海平面变化的空间分布 addpath(…

【Dart 教程系列第 49 篇】什么是策略设计模式?如何在 Dart 中使用策略设计模式

这是【Dart 教程系列第 49 篇】,如果觉得有用的话,欢迎关注专栏。 博文当前所用 Flutter SDK:3.22.1、Dart SDK:3.4.1 文章目录 一:什么是策略设计模式?二:为什么要使用策略设计模式&#xff1…

UG NX2406 安装教程

软件介绍 UG是一个交互式CAD/CAM(计算机辅助设计与计算机辅助制造)系统,它功能强大,可以轻松实现各种复杂实体及造型的建构。 它在诞生之初主要基于工作站,但随着PC硬件的发展和个人用户的迅速增长,在PC上的应用取得了迅猛的增长…

西蒙学习法

西蒙学习法 一根筋,挖死坑;会思考,持续不断的思考;会问问题,有深度的问题;一直想一个问题的解决办法; 资料 《世界十大学习方法》之西蒙学习法