2016-05-25 21 views
2

heapsを使用して優先度キューを構築しました。キューにはメッセージが含まれています。メッセージは優先順位に関する順序で送信する必要があります。Python:優先度として優先度キュー

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

ので、優先順位、次のメッセージを送信することは容易である:ただし、優先順位の値として、私は、メッセージが送信されるまでの時間は、例えば、私はキューに入れて持っているメッセージのセットを持っています。しかし、最初にmessag3をキューに入れてから5秒後に送信する場合は、次のメッセージmessage1がキューに入れられてから10秒後に送信されるようにしたいと考えています。message3送信します。どのように私はそれを行うことができますどのような例を知っていますか?

+2

メッセージが送信されるべきであることを実際の時間を保存するために容易になるだろうように思える(例えば 'datetime.datetime'ここでは実際にはその短い例ですインスタンス)。どの時点でも、メッセージを送信するまでの時間を計算するのは簡単です。 – mgilson

+0

前のコメント作成者は正しいです:意味のある時間関連のスケジューリングでは、絶対的なタイムスタンプを使用する必要があります。そうでなければ小さな時間エラーを累積します。 – Markus

答えて

2

優先度の値としてエポックを使用できます。タイマーが発生するたびに、現在時刻に基づいて再度発生するタイミングを計算します。

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 
+0

'start()'はヒープが空であるかどうかを調べるべきでしょうか? – Markus

+0

@ Markusはい、それは私が言うことができる限りでなければなりません – niemmi

+0

何かを学んだことがあります: 'xが' xと同じであると思われ、len(x)> 0'ならxとなります。 – Markus