常见的网站类型,长春二道网站建设,深圳室内装修公司,asp 开发的大型网站目录 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安装
安装指令#xff1a; yum -y update yum i…目录 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 varexp1, 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)
end2.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 c686f316aaf1eb01d5a4de1b0b63cd233010e63d3.2简易锁Lua脚本
加锁
pslua脚本中指令要对应单引号
//判断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 uuid3.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(lockCount0)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(lockCount0) 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;