起因:幾年前爲了開發一個監控系統,需要週期性的對系統狀態進行檢查,因此需要對檢查任務進行添加,排隊(按時間),移除等操作,無意中發現java jdk 中有DelayQueue,因此實現了一個python版本
源碼如下:
# -*- coding:utf-8 -*-
# python 版的 DelayQueue 類 和 Delayed 接口
#
from Queue import PriorityQueue
from datetime import datetime
import threading
class Delayed(object):
# 返回:計劃執行時間
# 單位: datetime
def plan_time(self):
pass
def total_seconds(td):
return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
class DelayQueue(PriorityQueue):
def __init__(self, maxsize):
self.queue = []
# 如果任務沒有到達執行時間,則消費者必須等待在此condition上
self.lock = threading.Lock()
self.can_done = threading.Condition(self.lock)
def put_task(self, task):
self.put((task.plan_time, task))
# 檢索並移除此隊列的頭部,如果此隊列不存在未到期延遲的元素,則等待它
def take_task(self):
self.can_done.acquire()
try:
task = self.peek()
delta = total_seconds(task.plan_time - datetime.now())
while delta > 0:
self.can_done.wait(delta)
task = self.peek()
delta = total_seconds(task.plan_time - datetime.now())
item = self.get()
self.can_done.notify_all()
return item[1]
finally:
self.can_done.release()
def peek(self):
self.not_empty.acquire()
try:
while not self._qsize():
self.not_empty.wait()
return self.queue[0][1]
finally:
self.not_empty.release()
PS: python 中的 PriorityQueue基於 最小堆 算法的,添加和移除一個元素的耗時都是log2(n)