Lua脚本简单理解
目录
1.安装
2.语法
2.1Lua数据类型
2.2变量
2.3lua循环
2.4流程控制
2.5函数
2.6运算符
2.7关系运算符
3.lua脚本在redis中的使用
3.1lua脚本再redis简单编写
3.2普通锁Lua脚本
3.3可重入锁lua脚本
1.安装
centos安装
安装指令:
yum -y update
yum install lua
启动指令:
lua
print("hello world")
windos安装
Lua Binaries Download
解压后在环境变量配置
再cmd中尝试,安装成功
也可以在idea中使用
2.语法
2.1Lua数据类型
nil 表示无效值。相当于false
boolean 包含两个值:false,true
number 双精度浮点数
string 字符串由一对双引号或者单引号表示
function 由c或lua编写函数
table lua中的表(taboe) “关联数组“(associative arrays),数组的索引可以是数字、字符串或表类型。在lua里,table的创建是通过"构造表达式完成",最简单构造表达式是{}。
-- 变量
print(type(nil))
print(type(false))
print(type(1))
print(type(1.1))
print(type(type))
print(type("hello world"))
print(type({1,2}))
2.2变量
Lua变量有三种类型:全局类型、局部变量、表中的域
- 没有使用local进行修饰的变量都是全局变量,使用local修饰的则为局部变量
- 局部变量的作用域为从声明位置开始到所在语句块结束
- 变量默认值都为nil
--变量
a = 5 --全局变量
print(a) -- 5
local b = 6 --局部变量
print(b) -- 6-- 查看变量、全局变量、局部变量
dolocal c = 4print(a) -- 5print(c) -- 4
end
print(c) -- nil--对多个变量同时赋值 ..表示为字符串连接
a, b, c= 1,2 -- 没有值的变量,赋值nil
print(a .."-" .. b)
print(c)
a, b = 2,3,4 --多出来的值被省略
print(a .. "-" .. b)-- table赋值 如果key值一样后面的会覆盖前面的值
tal = {"a", "b", "3"}
print(tal[1] .. tal[2] .. tal[3])
tal = {key = "xxddd", key1 = "yysss"}
print(tal["key"] .. tal["key1"])
2.3lua循环
--while 循环
a = 1
while(a < 5) doprint(a)a = a + 1
end
--for 循环,从exp1开始循环到exp2, exp3是步⻓
for var=exp1, exp2, xep3 do
end
for i = 1, 5, 1 doprint(i)
end
for i = 5, 1, -1 doprint(i)
end
--打印数组
a = {"one", "two", "three"}
for i, v in ipairs(a) doprint(i, v)
end
2.4流程控制
--流程控制
a = 9
if (a < 10) thenprint("⼩于10")
end
a = 11
if (a < 10) thenprint("⼩于10")
elseprint("⼤于等于10")
end
a = 10
if (a < 10) thenprint("⼩于10")
elseif (a == 10) thenprint("等于10")
elseprint("⼤于10")
end
2.5函数
--函数
function max(a, b)if (a < b) thenprint("a⼩于b")elseif(a == b) thenprint("a等于b")elseprint("a⼤于b")end
end
print(max(5, 5))--函数作为参数传递给函数
myFunc = function(param)print("这是param" .. param)
end
function myFuncB (a, b, func)result = a + bfunc(result)
end
myFuncB(1, 2, myFunc)--可变参数函数
function aa(...)local arg={...}for i, v in pairs(arg) doprint(i .. v)end
end
aa("a", "b", "c")
2.6运算符
正常+ - * / % ^ - 特殊//整除运算符 比如5//2 输出结果为2
算数运算符号
--算术运算符
print(1 + 2)
print(2 - 1)
print(2 * 1)
print(-10)
print(10 / 6)
print(10 % 6)
print(10 // 6)
print(10 ^ 2)
2.7关系运算符
正常 == > < >= <=
特殊:~=(不等于)
关系运算符
and or not
其他运算符号
.. 连接两个字符串
# 一元运算符,返回字符串或表的长度
#“hello” 返回5
3.lua脚本在redis中的使用
3.1lua脚本再redis简单编写
redis中支持使用EVAL关键字来使用Lua脚本
eval指令中的1 表示key的个数,以下代码实例是表示keys[1] 等于在1的后面的key1,即keys[1]=key1,但是value中是不需要声明的。
EVAL script numkeys key [key …] arg [arg …]127.0.0.1:6379> eval "return {KEYS[1],ARGV[1],ARGV[2]}" 1 key1 arg1 arg2
1) "key1"
2) "arg1"
3) "arg2"
127.0.0.1:6379>
在redis中执行
eval 执行执行
这个keys和argv必须是大写,不然会报错
eval "return redis.call('set',KEYS[1],ARGV[1])" 1 name xiaoming
也可以把指令进行缓存
script load ->evalsha 对应id
script load "return redis.call('set',KEYS[1],ARGV[1])"
返回:c686f316aaf1eb01d5a4de1b0b63cd233010e63devalsha c686f316aaf1eb01d5a4de1b0b63cd233010e63d 1 name1 zhangsanevalsha c686f316aaf1eb01d5a4de1b0b63cd233010e63d 1 name2 zhangsan2--判断指令是否存在
script exists c686f316aaf1eb01d5a4de1b0b63cd233010e63d--删除指令
script flush c686f316aaf1eb01d5a4de1b0b63cd233010e63d
3.2简易锁Lua脚本
加锁
ps:lua脚本中指令要对应单引号
//判断redis中是否存在key
// 如果不存在,那么就使⽤set key value,并且增加过期时间,返回1.
// 如果存在,直接返回0,继续循环获取锁
//正常编写
if (redis.call('exists',lockName) == 0) thenredis.call('set',lockName,uuid);redis.call('pexpire',lockName,30000)return 1;
elsereturn 0;
end;//替换成脚本
if (redis.call('exists',KEYS[1]) == 0) thenredis.call('set',KEYS[1],ARGV[1]);redis.call('pexpire',KEYS[1],ARGV[2])return 1;
elsereturn 0;
end;
在redis中跑一遍
eval "if (redis.call('exists',KEYS[1]) == 0) then redis.call('set',KEYS[1],ARGV[1]); redis.call('pexpire',KEYS[1],ARGV[2]) return 1; else return 0; end" 1 lockName uuid 30000
释放锁
//判断锁是否存在,如果不存在,直接返回0
//如果锁存在,判断value是否==当前线程的uuid
// 如果等于,执⾏delete
// 如果不等于,返回0
//正常写
if (redis.call('exists',lockName) == 0) thenreturn 0;
end;
if (redis.call('get',lockName) == uuid) thenredis.call('del',lockName)return 1;
elsereturn 0;
end;if (redis.call('exists',KEYS[1]) == 0) thenreturn 0;
end;
if (redis.call('get',KEYS[1]) == ARGV[1]) thenredis.call('del',KEYS[1])return 1;
elsereturn 0;
end;
reids执行脚本
eval "if (redis.call('exists', KEYS[1]) == 0) then return 0; end; if (redis.call('get', KEYS[1]) == ARGV[1]) then redis.call('del', KEYS[1]); return 1; else return 0; end;" 1 lockName uuid
3.3可重入锁lua脚本
可以通过hash的数据结构进行对锁的添加次数,和扣减测试进行设置
加锁
//redis中执⾏可重⼊加锁lua脚本
eval "if(redis.call('exists',KEYS[1]) == 0) then redis.call('hincrby',KEYS
[1],ARGV[1],1); redis.call('pexpire',KEYS[1],ARGV[2]) return 1; end; if(re
dis.call('hexists',KEYS[1],ARGV[1]) == 1) then redis.call('hincrby',KEYS
[1],ARGV[1],1); redis.call('pexpire',KEYS[1],ARGV[2]) return 1; else retur
n 0; end;" 1 lockName uuid 30000
//可重⼊加锁lua脚本//判断锁是否存在//如果不存在,就加锁,设置过期时间//如果存在,判断加锁的线程是不是⾃⼰//如果是,重⼊次数+1//如果不是,加锁失败
if(redis.call('exists',KEYS[1]) == 0) thenredis.call('hincrby',KEYS[1],ARGV[1],1);redis.call('pexpire',KEYS[1],ARGV[2])return 1;
end;
if(redis.call('hexists',KEYS[1],ARGV[1]) == 1) thenredis.call('hincrby',KEYS[1],ARGV[1],1);redis.call('pexpire',KEYS[1],ARGV[2])return 1;
elsereturn 0;
end;
解锁
//redis中执⾏可重⼊解锁lua脚本
eval "if(redis.call('hexists',KEYS[1],ARGV[1]) == 0) then return 0; end; l
ocal lockCount = redis.call('hincrby',KEYS[1],ARGV[1],-1) if(lockCount>0)t
hen redis.call('pexpire',KEYS[1],ARGV[2]); return 1; else redis.call('de
l',KEYS[1]) return 1; end;" 1 lockName uuid 30000 //可重⼊解锁lua脚本//判断锁是否存在且存在是否是本线程加的锁。也就是加锁线程是否本身//如果不是本身,直接就return 0,解锁失败了。//如果是本身,判断当前重⼊次数是否⼤于1//如果⼤于1,说明存在线程多次获取⼀把锁,此时只需要减1即可//如果不⼤于0,说明锁可以被删除了。
if(redis.call('hexists',lockName,uuid) == 0) then
return 0;
end;
local lockCount = redis.call('hincrby',lockName,uuid,-1)
if(lockCount>0) then
redis.call('pexpire',lockName,time);return 1;
else
redis.call('del',lockName) return 1;
end;
续约
//redis执⾏续约lua脚本
eval "if(redis.call('hexists',KEYS[1],ARGV[1])==0) then return 0; else red
is.call('pexpire',KEYS[1],ARGV[2]) return 1; end;" 1 lockName uuid 30000
//lua脚本
//判断锁是否是本线程加锁,是的话,就⼀直延⻓时间
if(redis.call('hexists',KEYS[1],ARGV[1])==0) then
return 0;
else
redis.call('pexpire',KEYS[1],ARGV[2])
return 1;
end;
相关文章:

Lua脚本简单理解
目录 1.安装 2.语法 2.1Lua数据类型 2.2变量 2.3lua循环 2.4流程控制 2.5函数 2.6运算符 2.7关系运算符 3.lua脚本在redis中的使用 3.1lua脚本再redis简单编写 3.2普通锁Lua脚本 3.3可重入锁lua脚本 1.安装 centos安装 安装指令: yum -y update yum i…...
AutoSAR自适应平台架构总览--AP的初认识
AutoSAR自适应平台架构总览:AP 基础设施层(Foundation Layer)核心操作系统(Core OS)通信管理(Communication Management) 服务层(Services Layer)诊断服务(Diagnostics S…...

GPT-4o Mini:探索最具成本效益的小模型在软件开发中的应用
随着人工智能技术的迅猛发展,自然语言处理(NLP)领域也取得了显著的进步。OpenAI 最新发布的 GPT-4o Mini 模型,以其卓越的性能和极具竞争力的价格,成为了广大开发者关注的焦点。作为一名长期关注人工智能及其在软件开发…...

{Spring Boot 原理篇} Spring Boot自动装配原理
SpringBootApplication 1,Spring Boot 应用启动,SpringBootApplication标注的类就是启动类,它去实现配置类中的Bean的自动装配 SpringBootApplication public class SpringbootRedis01Application {public static void main(String[] args)…...

QEMU源码全解析 —— CPU虚拟化(10)
接前一篇文章: 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社 《深度探索Linux系统虚拟化原理与实现》—— 王柏生 谢广军, 机械工业出版社 特此致谢! 二、x86架构CPU虚拟化 3. VMX 上一回讲解了支…...
46、PHP实现矩阵中的路径
题目: PHP实现矩阵中的路径 描述: 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向…...

c++笔记2
目录 2.2 栈底(bottom) } 大数乘大数 节点:包含一个数据元素及若干指向子树分支的信息 。 节点的度:一个节点拥有子树的数目称为节点的度 。 叶子节点:也称为终端节点,没有子树的节点或者度为零的节点…...
通过Lua脚本手写redis分布式锁
1、手写 Redis 分布式锁,包括上锁、解锁、自动续期。 此功能实现采用 Lua脚本实现,Lua脚本可以保证原子性。 setnx可以实现分布式锁,但是无法实现可重入锁,所以用hset来代替setnx实现可重入的分布式锁。 -- lock if redis.call…...
解析银行个人征信系统
银行个人征信系统,也被称为个人信用信息基础数据库或金融信用信息基础数据库,是我国社会信用体系的重要基础设施。该系统由中国人民银行组织国内相关金融机构建立,旨在依法采集、整理、保存、加工自然人(法人)及其他组…...

AttributeError: ‘list‘ object has no attribute ‘text‘
AttributeError: ‘list‘ object has no attribute ‘text‘ 目录 AttributeError: ‘list‘ object has no attribute ‘text‘ 【常见模块错误】 【解决方案】 示例代码 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英…...

Codeforces Round 874 (Div. 3)(A~D题)
A. Musical Puzzle 思路: 用最少的长度为2的字符串按一定规则拼出s。规则是:前一个字符串的尾与后一个字符串的首相同。统计s中长度为2的不同字符串数量。 代码: #include<bits/stdc.h> #include <unordered_map> using namespace std; #define N 20…...
[Python][基础语法]详细讲解
目录 1.顺序语句2.条件语句3.缩进和代码块4.空语句 pass5.循环语句1.while2.for3.continue4.break ∞.积累 1.顺序语句 默认情况下,Python的代码执行顺序是按照从上到下的顺序,依次执行# 输出结果:"123" print("1") pri…...
Layui---输入事件
输入实时监听 //监听表单单选框复选框选择 form.on(radio, function (data) {console.log(data.value); //得到被选中的值 });//监听表单下拉菜单选择form.on(select, function (data) //监听表单下拉菜单选择form.on(select, function (data) //监听表单复选框选择form.…...

甄选范文“论软件测试中缺陷管理及其应用”软考高级论文,系统架构设计师论文
论文真题 软件缺陷指的是计算机软件或程序中存在的某种破坏正常运行能力的问题、错误,或者隐藏的功能缺陷。缺陷的存在会导致软件产品在某种程度上不能满足用户的需要。在目前的软件开发过程中,缺陷是不可避免的。软件测试是发现缺陷的主要手段,其核心目标就是尽可能多地找…...
spring框架实现滑动验证码功能
spring框架实现滑动验证码功能 1. 整体描述2. 具体实现2.1 滑动验证码实体类2.2 滑动验证码登录VO2.3 滑动验证码接口返回类2.4 滑动验证码工具类2.5 滑动验证码Service2.6 滑动验证码Controller 3 工程源码4 总结 1. 整体描述 之前项目需要在验证码模块,增加滑动验…...

Pytorch使用教学8-张量的科学运算
在介绍完PyTorch中的广播运算后,继续为大家介绍PyTorch的内置数学运算: 首先对内置函数有一个功能印象,知道它的存在,使用时再查具体怎么用其次,我还会介绍PyTorch科学运算的注意事项与一些实用小技巧 1 基本数学运算…...
[Spring Boot]登录密码三种加密方式
简述 介绍其三种密码加密方法 1.SM2加密与验签 2.随机密码盐加密 3.MD5加密 推荐使用方法1,其次使用方法2,最不推荐的是方法3。方法3极其容易被密码字典破解,如果项目进行安全测试,通常是不允许的加密方式。 SM2加密与验签 引入…...

前端面试项目细节重难点分享(十三)
面试题提问:分享你最近做的这个项目,并讲讲该项目的重难点? 答:最近这个项目是一个二次迭代开发项目,迭代周期一年,在做这些任务需求时,确实有很多值得分享的印象深刻的点,我讲讲下面…...

每天五分钟深度学习:向量化方式完成逻辑回归m个样本的前向传播
本文重点 我们已经知道了向量化可以明显的加速程序的运行速度,本节课程将使用向量化来完成逻辑回归的前向传播,不使用一个for循环。 逻辑回归的前向传播 我们先来回忆一下逻辑回归的前向传播,如果我们有m个训练样本,首先对第一个样本进行预测,我们需要计算z,然后计算预…...
以线程完成并发的UDP服务端
网络(九)并发的UDP服务端 以线程完成功能 客户端 // todo UDP发送端 #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <stdlib.h> #include <string.h…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...