lua脚本延迟10秒怎么写
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lua脚本延迟10秒怎么写相关的知识,希望对你有一定的参考价值。
参考技术A 在Lua脚本中实现延迟可以使用以下方法:使用sleep函数。Lua标准库中没有提供sleep函数,但是可以通过C语言库实现。例如,使用luasocket库可以实现sleep功能,具体代码如下:
lua
Copy code
socket = require("socket")
socket.sleep(10) -- 休眠10秒
使用coroutine.yield()。在协程中使用yield函数可以实现暂停程序执行一段时间的效果,从而实现延迟。例如,下面的代码使用协程实现了延迟10秒的效果:
lua
Copy code
function delay()
local start = os.time()
while os.time() - start < 10 do
coroutine.yield()
end
end
co = coroutine.create(delay)
-- 执行协程,暂停10秒
while coroutine.status(co) ~= "dead" do
coroutine.resume(co)
end
这段代码定义了一个名为delay的函数,该函数使用while循环在10秒钟内不断地调用yield函数,从而实现延迟10秒的效果。在主程序中,创建了一个协程并在while循环中不断地调用resume函数来执行协程,直到协程执行结束为止。
2022年12月 .NET CORE工具案例-CSRedis执行Lua脚本实现商品秒杀
文章目录
前言
下面是Redis分布式锁常用的概念说明:设置、获取、过期时间、删除。
1、 Setnx
- 命令:SETNX key value
- 说明:将 key 的值设为 value ,当且仅当 key 不存在。若给定的 key 已经存在,则 SETNX 不做任何动作。SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。 时间复杂度:O(1)
- 返回值:设置成功,返回1 ; 设置失败,返回 0
2、Getset
- 命令:GETSET key value
- 说明:将给定 key 的值设为 value ,并返回 key 的旧值(old value)。当 key 存在但不是字符串类型时,返回一个错误。 时间复杂度:O(1)
- 返回值:返回给定 key 的旧值; 当 key 没有旧值时,也即是, key 不存在时,返回 nil 。
3、Expire
- 命令:EXPIRE key seconds
- 说明:为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。 时间复杂度:O(1)
- 返回值:设置成功返回 1 ;当 key 不存在或者不能为 key 设置生存时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的生存时间),返回 0 。
4、Del
- 命令:DEL key [key …]
- 说明:删除给定的一个或多个 key 。不存在的 key 会被忽略。 时间复杂度:O(N); N 为被删除的 key 的数量。删除单个字符串类型的 key ,时间复杂度为O(1)。 删除单个列表、集合、有序集合或哈希表类型的 key ,时间复杂度为O(M), M为以上数据结构内的元素数量。
锁的分类说明:
相对方 | 相对方 |
---|---|
悲观锁 | 乐观锁 |
公平锁 | 非公平锁 |
独享锁 | 共享锁 |
线程锁 | 进程锁 |
一、CSRedis执行Lua脚本实现商品秒杀
以下以.NET 7控制台为实例测试
1.单线程模拟多线程进行秒杀
using CSRedis;
Console.WriteLine("Hello World!");
//连接redis客户端
CSRedisClient redisClient = new CSRedisClient("127.0.0.1:6379,defaultDatabase=1");
//锁键
var lockKey = "lockKey";
//库存数
var stockKey = "stock";
//设置库存数量为5
redisClient.Set(stockKey, 5);//商品库存
//lua脚本,也可以通过流形式加载进来
var releaseLockScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";//释放锁的redis脚本
redisClient.Del(lockKey);//测试前,先把锁删了.
//------------------Parallel可以控制线程的执行顺序-----------------------------------
//ParallelOptions parallelOptions = new ParallelOptions();
//parallelOptions.MaxDegreeOfParallelism = 2;//最大并行数
//Parallel.For(0, 10, parallelOptions, t => this.DoSomethingLong($"btnParallel_Click_t"));
Parallel.For(0, 10, i =>
var id = Guid.NewGuid().ToString("N");
//获取锁,有效期5秒,防止死锁产生
do
//set : key存在则失败,不存在才会成功,并且过期时间5秒
var success = redisClient.Set(lockKey, id, expireSeconds: 5, exists: RedisExistence.Nx);
if (success == true)
break;
Thread.Sleep(TimeSpan.FromSeconds(1));//休息1秒再尝试获取锁
while (true);
Console.WriteLine($"线程:Task.CurrentId 拿到了锁,开始消费");
//扣减库存
var currentStock = redisClient.IncrBy(stockKey, -1);
if (currentStock < 0)
Console.WriteLine($"库存不足,线程:Task.CurrentId 抢购失败!");
redisClient.Eval(releaseLockScript, lockKey, id);
return;
//模拟处理业务,这里不考虑失败的情况
Thread.Sleep(TimeSpan.FromSeconds(new Random().Next(1, 3)));
Console.WriteLine($"线程:Task.CurrentId 消费完毕!剩余 currentStock 个");
//业务处理完后,释放锁.
redisClient.Eval(releaseLockScript, lockKey, id);
);
2.多线程进行秒杀
运行两个进程测试秒杀情况
using CSRedis;
Thread.Sleep(500);
Console.WriteLine("Hello World!");
CSRedisClient redisClient = new CSRedisClient("127.0.0.1:6379,defaultDatabase=1");
var lockKey = "lockKey";
//库存数
var stockKey = "stock";
//设置库存数量为5
redisClient.Set(stockKey, 10000, exists: RedisExistence.Nx);//商品库存
for (int i = 0; i < 100; i++)
Thread.Sleep(500);
var releaseLockScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";//释放锁的redis脚本
var id = Guid.NewGuid().ToString("N");
//set : key存在则失败,不存在才会成功,并且不过期
var success = redisClient.Set(lockKey, id, expireSeconds: -1, exists: RedisExistence.Nx);
if (success != true)
Console.WriteLine("当前资源以被占用,没机会了,等10秒钟再次尝试");
Thread.Sleep(1000);//休息1秒再尝试获取锁
continue;
else
Console.WriteLine($"线程:Task.CurrentId 拿到了锁,开始消费");
///业务操作
var currentStock = redisClient.IncrBy(stockKey, -1);
if (currentStock < 0)
Console.WriteLine($"库存不足,线程:Task.CurrentId 抢购失败!");
redisClient.Eval(releaseLockScript, lockKey, id);
return;
//模拟处理业务,这里不考虑失败的情况
Thread.Sleep(TimeSpan.FromSeconds(new Random().Next(1, 3)));
Console.WriteLine($"线程:Task.CurrentId 消费完毕!剩余 currentStock 个");
//业务处理完后,释放锁.
redisClient.Eval(releaseLockScript, lockKey, id);
以上是关于lua脚本延迟10秒怎么写的主要内容,如果未能解决你的问题,请参考以下文章