需求:订单超时,如规定每个订单创建后1小时未处理,就超时
lock = 订单创建时间 + 1h
方法一:轮询,查询表,判断当前时间 >= lock,则执行更改订单状态任务, 效率低
方法二:被动式,用户查询该订单时,判断从而修改订单状态,被动,且不查询永远不超时
方法三: 利用线程的timer函数,每一个订单创建就开启一个线程,执行timer函数,相当于定时任务
from threading import Timer
def delayed(seconds):
def decorator(f):
def wrapper(*args, **kargs):
t = Timer(seconds, f, args, kargs)
t.start()
return wrapper
return decorator
@delayed(3)
def xiaorui():
print "xiaorui.cc"
for i in range(10):
xiaorui()
方法四: 环形队列,处理延迟消息,只开启一个线程处理
- 创建一个环形队列一共为3600格,每格里是一个任务集合set(task)
- 创建一个timer,设定一个指针,默认current_index=1 ,指向队列的第一个格子,每一秒向后面走一格
- 任务集合包括3个参数,对象(订单号),cycle_num(圈数),任务函数
执行流程:
current_index 不断的走,每秒移动到一个新的格子,对应一个任务集合,通过set的判断cycle_num值是否为0执行不同的操作
如: 订单创建时间,2小时后超时,即表示7200秒后执行超时任务
cycle_num = 7200%3600 = 2
如果为0, 表示task马上快要执行了,取出任务函数来执行(开启一个线程执行),并删除任务set
如果不为0,表示还要转圈,将cycle_num的值-1 即可
环形队列的实现
https://blog.csdn.net/wangsiyu34567/article/details/82822766
队列的存储结构中使用的最多的是循环队列。循环队列包括两个指针, front 指针指向队头元素, rear 指针指向队尾元素的下一个位置。
队列为空的判断条件是:
front == rear
队列满的判断条件是
(rear+1)%maxsize == front
队列长度的计算公式:
(rear-front+maxsize)%maxsize
正常情况下当front == rear是队列有可能是满也有可能是空,为了区分这两种情况 我们需要在front前添加一个闲置单元。
class MyCircularQueue:
def __init__(self, k):
"""
Initialize your data structure here. Set the size of the queue to be k.
:type k: int
"""
self.queue = [None] * (k + 1)
self.maxsize = (k + 1)
self.front = 0
self.rear = 0
def enQueue(self, value):
"""
Insert an element into the circular queue. Return true if the operation is successful.
:type value: int
:rtype: bool
"""
if self.isFull():
return False
self.queue[self.rear] = value
self.rear = (self.rear + 1) % self.maxsize
return True
def deQueue(self):
"""
Delete an element from the circular queue. Return true if the operation is successful.
:rtype: bool
"""
if self.isEmpty():
return False
self.queue[self.front] = None
self.front = (self.front + 1) % self.maxsize
return True
def Front(self):
"""
Get the front item from the queue.
:rtype: int
"""
if self.isEmpty():
return -1
return self.front
def Rear(self):
"""
Get the last item from the queue.
:rtype: int
"""
if self.isEmpty():
return -1
return self.rear
def isEmpty(self):
"""
Checks whether the circular queue is empty or not.
:rtype: bool
"""
return self.front == self.rear
def isFull(self):
"""
Checks whether the circular queue is full or not.
:rtype: bool
"""
return (self.rear + 1) % self.maxsize == self.front