【问题标题】:Python: priority queue with time as priorityPython:以时间为优先级的优先级队列
【发布时间】:2016-09-23 06:20:41
【问题描述】:

我使用heaps 构建了优先级队列。队列包含消息,这些消息应该按照优先级的顺序发送。但是,作为优先级值,我有一段时间后应该发送消息,例如我必须将一组消息放入队列:

(10, message1)
(15, message2)
(5, message3)

因此,按照优先级发送消息很容易。但是,如果我在将 messag3 放入队列 5 秒后首先发送它,我想确保下一条消息 message1 将在放入队列后 10 秒发送,给出 5 message3 发送后的秒数。有谁知道我如何做到这一点的任何例子?

【问题讨论】:

  • 似乎存储应该发送消息的实际时间会更容易(例如 datetime.datetime 实例)。在任何给定时间,都应该直接计算距离发送消息还有多长时间。
  • 前面的评论是正确的:对于任何有意义的时间相关的调度,你必须使用绝对时间戳,否则你会累积小的时间错误。

标签: python python-2.7 timer heap priority-queue


【解决方案1】:

您可以使用 epoch 作为优先级值,并且每次计时器触发时,都会根据当前时间计算应该何时再次触发。这是实践中的一个简短示例:

import calendar
import time
import heapq
from threading import Timer

def epoch():
    return calendar.timegm(time.gmtime())

start_time = epoch()
heap = []
timer = None

def add_message(seconds, content):
    top = heap[0] if heap else None
    heapq.heappush(heap, (epoch() + seconds, content))
    if timer and top != heap[0]:
        timer.cancel()
        start()

def start():
    global timer
    if heap:
        timer = Timer(heap[0][0] - epoch(), fire)
        timer.start()

def fire():
    _, message = heapq.heappop(heap)
    print '{}: {}'.format(epoch() - start_time, message)
    start()

add_message(10, 'message1')
add_message(15, 'message2')
add_message(5, 'message3')
start()
add_message(1, 'message4')

输出:

1: message4
5: message3
10: message1
15: message2

【讨论】:

  • start() 应该检查堆是否为空,不是吗?
  • @Markus 是的,它应该而且据我所知
  • 刚学到东西:if x 好像就相当于if x is not None and len(x) > 0
  • @Markus -- 好吧,这完全取决于x :-)。对于x == Noneif x: ... 不会执行 if 套件的主体。对于x 是一个序列(例如,列表、元组、字符串、...),if-suite 的主体将仅在序列包含超过 0 个项目时执行。所以你的陈述是假设x是这两种类型之一:-)
  • @mgilson 在语言参考中找到它:“在布尔运算的上下文中,以及当控制流语句使用表达式时,以下值被解释为假:假、无、数字零“
猜你喜欢
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 2023-04-02
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 2012-02-24
  • 1970-01-01
相关资源
最近更新 更多