时序锁

问题

我们传统的互斥锁,是不支持时序(按照抢锁的先后顺序获取锁。)
我们遇到一种情况,我们的一个任务超时时间设置的是30min。多个任务并发时,因为存在共享资源A,需要对共享资源A加阻塞锁,预计正常情况下每个任务会占用锁5分钟。

我们的异步任务框架,限制同时正在运行的并发任务的个数是3个。按照传统的思考方式,一个任务最多等待 2*5min,但是实际情况是,我们依次下发了10个任务a,b,c,d,e…,最后的执行结果是有些任务超时失败了。为什么会出现这种情况。

获取因为获取锁的不确定性导致了这样的一个获取锁的顺序,
时间线—占用锁的对象
5-10min-------------a(b,c在阻塞等待)
10-15min-----------c(a执行完成,b,d在阻塞等待锁)
15-20min-----------d(a,c执行完成,b,e在阻塞等待锁)
20-25min-----------e (a,c,d执行完成,b,f在等待锁)
25-30min-----------f(a,c,d,e执行完成,b,g在等待锁)
30-35min-----------g(a,c,d,e执行完成,b执行超时,任务失败

若干任务失败。

如何让任务能够按照我们所期望的按照到来的顺序,占用锁呢?

解决方案

这其实就是一个队列的原理,先进先出呗;在我们原来的互斥锁的基础上,前面加一个队列。挖个坑,我们的锁是怎么实现的呢?且听下回分解,基于文件锁实现的,为什么基于文件锁实现而不使用threading库中的互斥锁,因为web程序是多进程的。
先简单介绍一下我们原来的阻塞锁,循环sleep等待delay秒,一直到获取到锁或者超时。
借助redis的队列,
在这里插入图片描述

实现

源码实现,注意考虑下面几个异常点:

  1. 系统时间的不可靠
  2. 缓存的不可靠
  3. redis操作的原子性

扩展

  1. 减少锁冲突,的另一个方法是减小锁的粒度。
  2. 依赖系统时间不是一个好的办法(耦合了系统时间,修改系统时间将会影响到此程序,而且写此程序的时候需要考虑),最好是能依赖系统的uptime,这样能减少对系统时间的耦合。
  3. redis 事务操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值